官方文檔:https://docs.mongodb.com/manual/replication/ 關於ReplSet的文檔
https://docs.mongodb.com/manual/reference/configuration-options/#replication-options 關於ReplSet的設置的文檔
參考文章:[MongoDB] 安裝MongoDB配置Replica Set
Replication:主從結構,一個Primary,多個Secondary,可能會有Arbitry。 Primary掛掉之后,會選舉出一個Secondary作為Primary,與zookeeper類似。 Arbitry上面不存數據,只是為了湊數。選舉算法要求節點數必須是奇數個,如果Primary+Secondary不是奇數個,就要用Arbitry湊數。 寫數據只能在Primary,讀數據默認也在Primary,可以配置成從Secondary讀,可以選最近的節點。 數據在Primary上寫成功之后,會將操作記錄在oplog中,Secondary將oplog拷貝過去,然后照着操作一遍,就有數據了。 Primary和Secondary上面的數據保證最終一致性,可以為寫操作配置write concern,有幾個級別:在Primary上寫完就認為寫成功;寫到oplog后認為寫成功;寫到一個/多個/某個/某幾個Secondary之后認為寫成功,等等。
前提:已經有若干台Ubuntu服務器已經安裝了mongodb服務,並且已經打開了服務器外訪問,關於Ubuntu安裝mongodb服務,請參考《Ubuntu 16.04 LTS 安裝Mongodb 3.4》
服務器IP ==》新IP 服務器名 節點
192.168.31.209==》192.168.31.210 mongodbServer01 主節點
192.168.31.198==》192.168.31.211 mongodbServer02 副節點
192.168.31.171==》192.168.31.212 mongodbServer03 副節點
設置固定IP配置文件
auto enp0s3 iface enp0s3 inet static #固定IP address 192.168.31.210 #IP地址 netmask 255.255.255.0 #子網掩碼 gateway 192.168.31.1 #網關 dns-nameservers 192.168.31.1 #DNS,我目前使用的是小米的路由器,以上為我的配置
借用官方的圖
第一步:修改mongod配置文件(三台服務器都需要操作)
sudo vi /etc/mongod.conf
需要增加的內容即復制集設置中的內容
repliocation: oplogSizeMB: 1024 replSetName: wesDemoRS
參數說明:
replication.oplogSizeMB
數字,復制操作日志的最大大小(M),該mongod過程基於最大可用空間量創建一個oplog,對於64位系統,oplog通常是可用磁盤的5%,一旦mongod第一次創建了oplog,更改replication.oplogSizeMB將不會影響oplog的大小
replication.replSetName
字符,作為其mongod部分副本集的名稱,副本集中的所有主機都必須具有相同的名稱,如果應用程序連接到多個副本集,則每個集合應具有不同的名稱,某些驅動程序組副本通過副本集名稱設置連接
replication.secondaryIndexPrefetch
字符,僅適用於mmapv1存儲引擎,在從oplog應用操作之前,副本集的輔助成員加載到內存中的索引,默認情況下,在從oplog應用操作之前,二進制文件將與操作相關的所有索引加載到內存中,可選的值有none/all/_id_only,該設置僅適用於mongod
replication.enableMajorityReadConcern
布爾值,默認為False,版本3.2后的新功能
第二步:重新啟動mongodb服務(三台服務器都需要操作)
sudo service mongod restart sudo service mongod status
第三步:在mongodb主服務器(192.168.31.210)運行命令,啟動復制集
#連接mongodb
mongo
#使用admin數據庫
use admin
#查看當前的ReplSet的狀態
rs.status()
初始化復制集並查看復制集狀態,請參考《mongodb復制集搭建》
#初始化ReplSet復制集
rs.initiate({_id:'wesDemoRS',members:[{_id:1,host:'192.168.31.210:27017'}]})
#查看ReplSet復制集狀態
rs.status()
第四步:復制集群增加其他服務器(192.168.31.211)
rs.add("192.168.31.211:27017");
rs.add("192.168.31.212:27017");
rs.status();
第五步:測試數據復制集效果,在主節點(192.168.31.210)上插入數據測試
use test
for(var i =0; i <4; i ++){db.user.insert({userName:'wes'+i,age:i})}
查看數據集,三個數據庫都有數據,復制數據功能已經運行成功!!
第六步:如主節點掉線,是否會故障轉移
現時是
192.168.31.210 主
192.168.31.211 副
192.168.31.212 副
模擬關閉主節點,在主節點,使用db.shutdownServer()命令
在兩個副節點查看現時的狀態,192.168.31.211變成了主節點,成功實現了故障轉移!!
當把原來的主節點重新啟動,查看復制集的狀態,原來的主節點31.210會變成副節點,主節點依然是原來的31.211
注意:192.168.31.210作為初始化時候的主節點,待服務器全部都重啟之后,192.168.31.210依然會變回主節點
其他:我們現時只能在主節點查詢數據,但如果想在副節點查詢到數據應該怎么做呢?可以在副節點運行以下命令
#在當前連接讓secondary可以提供讀操作
rs.slaveOk()
如果沒有運行命令之前,會出現以下錯誤
wesDemoRS:SECONDARY> show collections 2017-09-01T21:14:54.665-0700 E QUERY [thread1]Error: listCollections failed:{ "ok":0, "errmsg":"not master and slaveOk=false", "code":13435, "codeName":"NotMasterNoSlaveOk" }
參考: