啟用三個 mongod 建立復制集。
MongoDB 版本選擇目前最新的穩定版 3.6.2-jessie。
docker run --name mongo0 -d mongo:3.6.2-jessie --replSet "rs0" --bind_ip_all
docker run --name mongo1 -d mongo:3.6.2-jessie --replSet "rs0" --bind_ip_all
docker run --name mongo2 -d mongo:3.6.2-jessie --replSet "rs0" --bind_ip_all
通過 docker inspect 找到三個 mongod 實例的 IPAddress。
比如 docker inspect mongo0 | grep IPAddress,
又由於端口為 mongod 默認的 27017。所以 mongod 的地址為
- mongo0: 172.17.0.2:27017
- mongo1: 172.17.0.3:27017
- mongo2: 172.17.0.4:27017
初始化復制集
rs.initiate( {
_id : "rs0",
members: [
{ _id: 0, host: "172.17.0.2:27017" },
{ _id: 1, host: "172.17.0.3:27017" },
{ _id: 2, host: "172.17.0.4:27017" }
]
})
根據 replica-set-configuration-document,
_id:復制集的名稱。必須與啟動 mongod 的--replSet一致members:成員配置文件的列表。members[n]._id:用來識別成員的 idmembers[n].host:成員對應的host:port
連接字符串為
mongodb://172.17.0.2:27017,172.17.0.3:27017,172.17.0.4:27017/test?replicaSet=rs0
復制特性
在主節點中插入數據后,從節點中也存在。
mongo mongodb://172.17.0.2:27017,172.17.0.3:27017,172.17.0.4:27017/test?replicaSet=rs0
rs0:PRIMARY> db.order.insert({price: 1})
WriteResult({ "nInserted" : 1 })
mongo --host 172.17.0.3
// 允許當前連接對從庫進行讀操作
rs0:SECONDARY> db.getMongo().setSlaveOk()
rs0:SECONDARY> db.order.find()
{ "_id" : ObjectId("5a7c5473b74e8cf1bb890979"), "price" : 1 }
重新選舉
關閉主節點,會重新選舉出新的主節點。
當前主節點為 172.17.0.2:27017
> `rs.status()`
"name" : "172.17.0.2:27017",
"health" : 1,
"stateStr" : "PRIMARY",
通過 docker stop mongo0 關閉它之后,可以看到 172.17.0.2 是不健康狀態
"name" : "172.17.0.2:27017",
"health" : 0,
"stateStr" : "(not reachable/healthy)",
主節點變為了 172.17.0.3,期限由 1 變為了 2,表示又經過一次選舉,
"term" : NumberLong(2)
...
...
"name" : "172.17.0.3:27017",
"health" : 1,
"stateStr" : "PRIMARY",
docker start mongo0 啟動 mongo0 后,172.17.0.2 變為了健康的從節點
"name" : "172.17.0.2:27017",
"health" : 1,
"stateStr" : "SECONDARY",
大部分節點失效
我們關閉兩個節點
docker stop mongo0 mongo2
可以看到 172.17.0.2 和 172.17.0.4 都無法連接,而 172.17.0.3 變為了從節點,
整個復制集沒有主節點了,無法進行寫操作。
"name" : "172.17.0.3:27017",
"health" : 1,
"stateStr" : "SECONDARY",
"name" : "172.17.0.2:27017",
"health" : 0,
"stateStr" : "(not reachable/healthy)",
"name" : "172.17.0.4:27017",
"health" : 0,
"stateStr" : "(not reachable/healthy)",
設置優先級
先啟動之前關閉的節點 docker start mongo0 mongo2
根據 adjust-replica-set-member-priority
將第一個節點的 priority 設置為 2。(需要在主節點中輸入以下命令)
cfg = rs.conf()
cfg.members[0].priority = 2
rs.reconfig(cfg)
可以看到不久后,主節點變為 _id: 0 了
"_id" : 0,
"stateStr" : "PRIMARY",
用於生產環境的注意事項
- mongod 綁定非 localhost 地址前,考慮開啟訪問控制或者安全清單上的其他措施
- 復制集成員的關聯性應該小,減小同時出問題的幾率
參考
https://docs.mongodb.com/manual/tutorial/deploy-replica-set/
