1. 程式人生 > >配置mongodb複製集時遇見的坑

配置mongodb複製集時遇見的坑

最近在做mangodb複製集的時候,遇到了很多問題,為了讓以後的親在遇到類似的問題時可以找到資料以供參考,下面我就分享一下我遇到的問題已經解決方案。
我的是在一臺centos7的虛擬機器上配置mongodb複製集的,包括一個主節點(mongo27017)、兩個從節點(mongo27018/mongo27019)、一個投票節點(mongo27020)。四個mongodb資料庫都在home資料夾下的DataBase資料夾內。27017、27018這些數值表示該資料庫的埠。
這裡寫圖片描述
這裡寫圖片描述
首先,我們要在mongodb的配置檔案字尾(.config)中設定一些引數(我的配置檔案在bin目錄下),以mongo27018為例

port=27018
logpath=/home/wopelo/DataBase/mongo27018/data/log/mongodb.log
dbpath=/home/wopelo/DataBase/mongo27018/data/db
fork=true             //後臺啟動
logappend=true        //以新增而不是覆蓋的方式書寫日誌,
oplogSize=1024        //單位mb,同一複製集下該引數值須保持一致。當某個從節點從災難中恢復回來時,如果由於從節點無法工作而沒有寫入從節點的資料大於該值時,從節點重新複製主節點的所有資料。預設值為磁碟儲存空間的5%
replSet=iCopy         //複製集名稱

最關鍵的一個引數是replSet,它表示複製集的名稱,在同一個複製集下的資料庫,其配置檔案裡的replSet的值必須一致。
下面,開啟並進入到mongo27017,切換到admin資料庫,編寫config配置檔案

config={
    _id:"iCopy",
    members:[
        {_id:0,host:"127.0.0.1:27017"},
        {_id:1,host:"127.0.0.1:27018"},
        {_id:2,host:"127.0.0.1:27019",arbiterOnly:true}
    ]
}

arbiterOnly設定投票節點。這裡只寫了三個成員,而且投票節點是mongo27019,我們將在下面利用新增、刪除、修改和重新初始化這幾個操作把mongo27019設定為從節點,mongo27020設定為投票節點。
現在初始化複製集

(出現ok:1表示成功)

rs.initiate(config)

接下來可能會出現這樣的問題
這裡寫圖片描述
命令列提示投票節點中已有資料無法初始化,我不知道從節點會不會也發生這種問題,但我想這應該是因為mongodb為了保持資料一致性,資料只能寫到主節點中,從節點從主節點中獲取資料,投票節點不儲存資料,如果非主節點中原本就有資料,那麼主從節點的資料就不一樣了。雖然我的mongo27019真的沒有資料,但既然出現了問題,那就解決它。解決方法是先在mongo27019的配置檔案中把replSet刪掉,重啟資料庫之後在其每一個數據庫中使用

db.dropDatabase()

注意是所有資料庫,包括admin與local。如果不在配置檔案中刪除replSet的話,很可能會刪除失敗。在我們使用show dbs返回為空的時候就證明所有資料庫都已經被刪掉了,然後我們再把replSet添加回去,重新啟動mongo27019,再初始化一次就ok了。初始化之後mongo27017為主節點、27018為從節點、27019為投票節點。
之後,我們要新增mongo20720並把它設定為投票節點。這裡按道理我們可以直接修改config配置,把mongo27019設定為從節點,再新增一個新節點

config.members[2]={_id:2,host:"127.0.0.1:27019"}
config.members[3]={_id:3,host:"127.0.0.1:27020",arbiterOnly:true}

然後再重新初始化(如果出現ok:1就成功)

rs.reconfig(config)

雖然我們輸入config檢視配置檔案時,顯示的和我們預期的一樣,但在重新初始化時會報一個錯
這裡寫圖片描述

我們就採取一個比較保守的方法,先把mongo27019與mongo27020從config中刪除掉,再重新新增

rs.remove("127.0.0.1:27019")
rs.remove("127.0.0.1:27020")
rs.add("127.0.0.1:27019")
rs.add("127.0.0.1:27020")
config.members[3]={_id:3,host:"127.0.0.1:27020",arbiterOnly:true}
rs.reconfig(config)

之後我們再進入四個資料庫中(已經進入的話按enter),發現主從節點以及投票節點命令列提示已經變成
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
使用

rs.status()

檢視狀態,在members一項中我們可以看到目前複製集的所有節點及其屬性。比如在這裡我們可以看到mongo27020確實是投票節點
這裡寫圖片描述
我們隨便在主節點中新建一個數據庫,再隨便插入一些資料,然後到從節點中去檢視,如果出現下面的情況
這裡寫圖片描述
這是因為mongodb為了保證資料一致性,預設禁止在從節點中進行絕大部分操作,我們通過

rs.slaveOk(true)

處理之後就可以檢視從節點的資料了
而在投票節點中,雖然可以看到新建的資料庫,但我們使用find檢視裡面的資料時,會出現
這裡寫圖片描述
意思是這個節點不是主節點也不是從節點。作為投票節點的節點,不儲存資料。
另外還有一點,上面的步驟都是通過config=…….類似的形式修改配置檔案,這隻適合第一次編寫config的情況,也就是說你第一次在mongodb shell中配置config檔案。但你退出shell之後,再次進入shell就不能用config=…….類似的形式修改配置檔案,而且此時直接輸入config 是會報錯的,現在就只能通過rs.config()來檢視配置檔案。如果需要修改配置檔案的話,則需要將rs.config()賦予一個變數,修改變數,再rs.reconfig(變數)的方式修改配置檔案。
這裡寫圖片描述
這裡寫圖片描述
(這裡報了一個錯,意思是要設定複製延遲必須滿足priority為0,大家可以自行百度slaveDelay和priority的含義)
現在,我們就完成了複製集的搭建,也看到和避開了一些坑。謝謝大家,我的表演結束。