使用 Docker 部署 MongoDB 复制集

启用三个 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:用来识别成员的 id
    • members[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.2172.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/

posted @ 2018-02-08 22:39  Jay54520  阅读(2718)  评论(0编辑  收藏  举报