轉自http://zouqingyun.blog.51cto.com/782246/1679771 html
由三個節點組成的 複製集 爲網絡故障或是其餘的系統故障提供了足夠的冗餘。該複製集也有足夠的分佈式讀操做的能力。複製集應該保持奇數個節點,這也就保證了 選舉 能夠正常的進行nginx
用3臺已有的 mongod 實例來部署一個由三個節點組成的 複製集mongodb
mongodb-1 192.168.3.31
docker
mongodb-2 192.168.3.32數據庫
mongodb-3 192.168.3.33數組
在生產環境中,咱們應該將每一個節點部署在獨立的機器上,並使用標準的MongoDB端口 27017 。使用 bind_ip 參數來限制訪問MongoDB的應用程序的地址。安全
若使用了異地分佈式架構的複製集,請確保多數 mongod 實例節點位於主數據中心中。bash
確保各個節點之間能夠正常通信,且各個客戶端都處於安全的可信的網絡環境中。能夠考慮如下事項:網絡
創建虛擬的專用網絡。確保各個節點之間的流量是在本地網絡範圍內路由的。(Establish a virtual private network. Ensure that your network topology routes all traffic between members within a single site over the local area network.)架構
配置鏈接限制來防止未知的客戶端鏈接到複製集。
配置網絡設置和防火牆規則來對將MongoDB的端口僅開放給應用程序,來讓應用程序發的進出數據包能夠與MongoDB正常交流。
最後請確保複製集各節點能夠互相經過DNS或是主機名解析。咱們須要配置DNS域名或是設置 /etc/hosts 文件來配置。
MongoDB的安裝文檔請參考http://docs.mongoing.com/manual/core/read-preference.html
1.修改配置文件/etc/mongod.conf
#添加要複製的複製集名稱 replSet=testrs0 #添加這一行 #重啓mongodb服務 Stopping mongod: [ OK ] Starting mongod: [ OK ] [root@mongodb-1 ~]# netstat -anpt |grep mon tcp 0 0 0.0.0.0:28017 0.0.0.0:* LISTEN 1836/mongod tcp 0 0 0.0.0.0:27017 0.0.0.0:* LISTEN 1836/mongod #mongodb-2,mongodb-3同樣的操做,過程略 #配置本地hosts解析 [root@mongodb-1 ~]# tail -3 /etc/hosts 192.168.3.31 mongodb-1 192.168.3.32 mongodb-2 192.168.3.33 mongodb-3
2.初始化複製集
> rs.initiate() #初始化 { "info2" : "no configuration explicitly specified -- making one", "me" : "mongodb-1:27017", "ok" : 1 } testrs0:OTHER> rs.status() #查看狀態 { "set" : "testrs0", "date" : ISODate("2015-08-06T02:07:24.851Z"), "myState" : 1, "members" : [ { "_id" : 0, "name" : "mongodb-1:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 108, "optime" : Timestamp(1438826836, 1), "optimeDate" : ISODate("2015-08-06T02:07:16Z"), "electionTime" : Timestamp(1438826836, 2), "electionDate" : ISODate("2015-08-06T02:07:16Z"), "configVersion" : 1, "self" : true } ], "ok" : 1 }
3.將mongodb-2,mongodb-3加入到節點中
#經過 rs.add() 來將剩下的節點加入複製集 testrs0:PRIMARY> rs.add("mongodb-2:27017") #支持域名解析 { "ok" : 1 } testrs0:PRIMARY> rs.add("mongodb-3:27017") { "ok" : 1 } #查看最後結果 testrs0:PRIMARY> rs.status() { "set" : "testrs0", "date" : ISODate("2015-08-06T02:10:13.116Z"), "myState" : 1, "members" : [ { "_id" : 0, "name" : "mongodb-1:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 277, "optime" : Timestamp(1438827004, 1), "optimeDate" : ISODate("2015-08-06T02:10:04Z"), "electionTime" : Timestamp(1438826836, 2), "electionDate" : ISODate("2015-08-06T02:07:16Z"), "configVersion" : 3, "self" : true }, { "_id" : 1, "name" : "mongodb-2:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 19, "optime" : Timestamp(1438827004, 1), "optimeDate" : ISODate("2015-08-06T02:10:04Z"), "lastHeartbeat" : ISODate("2015-08-06T02:10:12.956Z"), "lastHeartbeatRecv" : ISODate("2015-08-06T02:10:12.029Z"), "pingMs" : 1, "syncingTo" : "mongodb-1:27017", "configVersion" : 3 }, { "_id" : 2, "name" : "mongodb-3:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 8, "optime" : Timestamp(1438827004, 1), "optimeDate" : ISODate("2015-08-06T02:10:04Z"), "lastHeartbeat" : ISODate("2015-08-06T02:10:12.968Z"), "lastHeartbeatRecv" : ISODate("2015-08-06T02:10:12.976Z"), "pingMs" : 5, "syncingTo" : "mongodb-1:27017", "configVersion" : 3 } ], "ok" : 1 } #在mongodb-1上查看節點狀態 testrs0:PRIMARY> rs.isMaster() { "setName" : "testrs0", "setVersion" : 3, "ismaster" : true, #表示當前節點是master節點 "secondary" : false, "hosts" : [ "mongodb-1:27017", "mongodb-2:27017", "mongodb-3:27017" ], "primary" : "mongodb-1:27017", "me" : "mongodb-1:27017", "electionId" : ObjectId("55c2c154479b3bb0dbd4a66a"), "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2015-08-06T02:11:40.419Z"), "maxWireVersion" : 3, "minWireVersion" : 0, "ok" : 1 } #在mongodb-2上查看節點狀態 testrs0:SECONDARY> rs.isMaster() { "setName" : "testrs0", "setVersion" : 3, "ismaster" : false, "secondary" : true, #顯示當前節點是slave狀態 "hosts" : [ "mongodb-1:27017", "mongodb-2:27017", "mongodb-3:27017" ], "primary" : "mongodb-1:27017", "me" : "mongodb-2:27017", "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2015-08-06T03:08:11.009Z"), "maxWireVersion" : 3, "minWireVersion" : 0, "ok" : 1 } #在mongodb-3上查看結果 testrs0:SECONDARY> rs.isMaster() { "setName" : "testrs0", "setVersion" : 3, "ismaster" : false, "secondary" : true, #顯示是slave狀態 "hosts" : [ "mongodb-1:27017", "mongodb-2:27017", "mongodb-3:27017" ], "primary" : "mongodb-1:27017", "me" : "mongodb-3:27017", "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2015-08-06T03:08:55.896Z"), "maxWireVersion" : 3, "minWireVersion" : 0, "ok" : 1 }
4.在主節點上建立數據,從節點是否獲取到
testrs0:PRIMARY> use testdb switched to db testdb testrs0:PRIMARY> db.testcoll.insert({Name: "test",Age: 50,Gender: "F"}) WriteResult({ "nInserted" : 1 }) testrs0:PRIMARY> db.testcoll.find() { "_id" : ObjectId("55c2c34071cd36e46b63e280"), "Name" : "test", "Age" : 50, "Gender" : "F" }
在從節點上查詢,是不能夠直接查詢,要使用一個命令rs.slave()把本身提高爲從節點
testrs0:SECONDARY> rs.slaveOk() testrs0:SECONDARY> use testdb switched to db testdb testrs0:SECONDARY> db.testcoll.find() { "_id" : ObjectId("55c2c34071cd36e46b63e280"), "Name" : "test", "Age" : 50, "Gender" : "F" }
5、中止mongodb-1的服務
[root@mongodb-1 ~]# hostname mongodb-1 [root@mongodb-1 ~]# /etc/init.d/mongod stop Stopping mongod: [ OK ] [root@mongodb-1 ~]# netstat -tunlp |grep mon #在mongodb-2上查看節點狀態 testrs0:PRIMARY> rs.isMaster() { "setName" : "testrs0", "setVersion" : 7, "ismaster" : true, "secondary" : false, "hosts" : [ "mongodb-1:27017", "192.168.3.32:27017", "192.168.3.33:27017" ], "primary" : "192.168.3.32:27017", "me" : "192.168.3.32:27017", "electionId" : ObjectId("55c2d5c12885e541bfce06ea"), "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2015-08-06T03:36:54.961Z"), "maxWireVersion" : 3, "minWireVersion" : 0, "ok" : 1 } #在mongodb-3上查看節點狀態 testrs0:SECONDARY> rs.isMaster() { "setName" : "testrs0", "setVersion" : 7, "ismaster" : false, "secondary" : true, "hosts" : [ "mongodb-1:27017", "192.168.3.32:27017", "192.168.3.33:27017" ], "primary" : "192.168.3.32:27017", "me" : "192.168.3.33:27017", "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2015-08-06T03:37:41.152Z"), "maxWireVersion" : 3, "minWireVersion" : 0, "ok" : 1 } #在mongodb-2上查看數據 testrs0:PRIMARY> db.testcoll.find() { "_id" : ObjectId("55c2c34071cd36e46b63e280"), "Name" : "test", "Age" : 50, "Gender" : "F" } { "_id" : ObjectId("55c2c4ca71cd36e46b63e281"), "Name" : "docker", "Age" : 50, "Gender" : "F" } { "_id" : ObjectId("55c2c58271cd36e46b63e282"), "Name" : "nginx", "Age" : 50, "Gender" : "F" } { "_id" : ObjectId("55c2c863581ac81241af5a9b"), "Name" : "test", "Age" : 50, "Gender" : "F" }
從新啓動mongodb-1的服務
[root@mongodb-1 ~]# /etc/init.d/mongod start Starting mongod: [ OK ] [root@mongodb-1 ~]# netstat -tunlp |grep mon tcp 0 0 0.0.0.0:28017 0.0.0.0:* LISTEN 1882/mongod tcp 0 0 0.0.0.0:27017 0.0.0.0:* LISTEN 1882/mongod
查看mongodb-1的節點狀態,默認會是slave狀態
testrs0:SECONDARY> rs.isMaster() { "setName" : "testrs0", "setVersion" : 7, "ismaster" : false, "secondary" : true, #結果顯示的是slave狀態 "hosts" : [ "mongodb-1:27017", "192.168.3.32:27017", "192.168.3.33:27017" ], "primary" : "192.168.3.32:27017", "me" : "mongodb-1:27017", "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2015-08-06T02:48:14.075Z"), "maxWireVersion" : 3, "minWireVersion" : 0, "ok" : 1 }
6.定義優先級
使用 rs.conf() 來查看 複製集配置對象 :
testrs0:SECONDARY> rs.conf() { "_id" : "testrs0", "version" : 7, "members" : [ { "_id" : 0, "host" : "mongodb-1:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, #優先級爲1 "tags" : { }, "slaveDelay" : 0, "votes" : 1 }, { "_id" : 1, "host" : "192.168.3.32:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : 0, "votes" : 1 }, { "_id" : 2, "host" : "192.168.3.33:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : 0, "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatTimeoutSecs" : 10, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 } } }
在主節點把mongodb-1的優先級定義爲2,讓它成爲主節點
將複製集配置對象複製給一個變量(如 mycfg )。而後經過該變量對該節點設置優先級。而後經過 rs.reconfig()來更新複製集配置。
注意,設置優先級用這個命令mycfg.members[數組中第幾個節點].priority = 2
#首先定義變量mycfg testrs0:PRIMARY> mycfg=rs.conf() { "_id" : "testrs0", "version" : 7, "members" : [ { "_id" : 0, "host" : "mongodb-1:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : 0, "votes" : 1 }, { "_id" : 1, "host" : "192.168.3.32:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : 0, "votes" : 1 }, { "_id" : 2, "host" : "192.168.3.33:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : 0, "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatTimeoutSecs" : 10, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 } } } #設置成員優先級 testrs0:PRIMARY> mycfg.members[0].priority = 2 #設置優先級爲2 2 testrs0:PRIMARY> rs.reconfig(mycfg) #從新讀取配置文件 { "ok" : 1 } #查看mongodb-2的狀態 testrs0:SECONDARY> rs.isMaster() { "setName" : "testrs0", "setVersion" : 8, "ismaster" : false, "secondary" : true, #已經由以前的master變成slave了 "hosts" : [ "mongodb-1:27017", "192.168.3.32:27017", "192.168.3.33:27017" ], "primary" : "mongodb-1:27017", "me" : "192.168.3.32:27017", "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2015-08-06T03:49:23.235Z"), "maxWireVersion" : 3, "minWireVersion" : 0, "ok" : 1 } #查看mongodb-1的狀態 testrs0:PRIMARY> rs.isMaster() { "setName" : "testrs0", "setVersion" : 8, "ismaster" : true, #已經從以前的slave變成master狀態了 "secondary" : false, "hosts" : [ "mongodb-1:27017", "192.168.3.32:27017", "192.168.3.33:27017" ], "primary" : "mongodb-1:27017", "me" : "mongodb-1:27017", "electionId" : ObjectId("55c2cc1fe60875284b735753"), "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2015-08-06T02:54:07.059Z"), "maxWireVersion" : 3, "minWireVersion" : 0, "ok" : 1 }
複製集參考
Replication Methods in the mongo Shell 命令 描述 rs.add() 爲複製集新增節點。 rs.addArb() 爲複製集新增一個 arbiter rs.conf() 返回複製集配置信息 rs.freeze() 防止當前節點在一段時間內選舉成爲主節點。 rs.help() 返回 replica set 的命令幫助 rs.initiate() 初始化一個新的複製集。 rs.printReplicationInfo() 以主節點的視角返回複製的狀態報告。 rs.printSlaveReplicationInfo() 以從節點的視角返回複製狀態報告。 rs.reconfig() 經過從新應用複製集配置來爲複製集更新配置。 rs.remove() 從複製集中移除一個節點。 rs.slaveOk() 爲當前的鏈接設置 slaveOk 。不推薦使用。使用 readPref() 和 Mongo.setReadPref() 來設置 read preference 。 rs.status() 返回複製集狀態信息。 rs.stepDown() 讓當前的 primary 變爲從節點並觸發 election 。 rs.syncFrom() 設置複製集節點從哪一個節點處同步數據,將會覆蓋默認選取邏輯。
複製集數據庫命令
命令 描述 replSetFreeze 防止當前節點在一段時間內選舉成爲主節點。 replSetGetStatus 返回複製集的狀態報告。 replSetInitiate 初始化一個新的複製集。 replSetMaintenance 開啓活關閉維護模式,維護模式將使 secondary 進入 RECOVERING 狀態。 replSetReconfig 爲已存在的複製集應用新的配置。 replSetStepDown 強制當前的 primary *降職*變爲 secondary ,並觸發選舉。 replSetSyncFrom 覆蓋默認的複製來源選取邏輯。 resync 強制 mongod 從新從 master 進行初始化複製。僅在主-從模式。 applyOps 內部命令應用 oplog 在如今的數據集上。 isMaster 返回該節點的角色信息,包括是否爲主節點。 getoptime 內部命令,返回optime。