主库进行写操作,两台从库进行读操作(至于某次读操作到底路由给了哪台,仲裁决定)。实现了读写分离。这还不止,假设主库宕掉,还能实现不须要用户干预的情况下。将主库自己主动切换到另外两台从库中的某一台,真正实现了 db 的高可用。
1. 背景
1.1 环境
- CPU核数:4
- 内存配置:8G
- 带宽:100MB
- 磁盘:系统盘 40G,数据盘 180G
- 操作系统版本号:Ubuntu 14.04 64位
1.2 系统部署结构图
2. MongoDB 副本集环境搭建
2.1 安装包下载
最新 MongoDB 安装包下载地址:
https://www.mongodb.org/downloads#production
选择适合我们操作系统的版本号下载。最新版本号是 mongodb-linux-x86_64-ubuntu1404-3.2.1.tgz,大小 74MB。
2.2 MongoDB 的安装和设置环境变量
解压到当前文件夹: 先把原来启动的实例依次关闭,顺序是两个 slave 节点、主节点、仲裁节点: 查看仲裁日志: 为了验证这个我们再将 27017 重新启动:
$ ):
$ ):
$ ):
$ ):
$ 2.4.4 生产库、生产用户的创建
rs1:SECONDARY>
rs1:SECONDARY>
rs1:PRIMARY>
rs1:SECONDARY>
rs1:PRIMARY> ,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2016-02-27T03:00:27.031Z"),
"lastHeartbeatRecv" : ISODate("2016-02-27T02:43:57.294Z"
),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "Connection refused",
"configVersion" : -1
},
{
"_id" : 1,
"name" : "somehost:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 2070279,
"optime" : {
"ts" : Timestamp(1456542007, 2),
"t" : NumberLong(3)
},
"optimeDate" : ISODate("2016-02-27T03:00:07Z"),
"lastHeartbeat" : ISODate("2016-02-27T03:00:26.860Z"),
"lastHeartbeatRecv" : ISODate("2016-02-27T03:00:27.287Z"
),
"pingMs" : NumberLong(0),
"syncingTo" : "somehost:27019",
"configVersion" : 4
},
{
"_id" : 2,
"name" : "somehost:27019",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 2070280,
"optime" : {
"ts" : Timestamp(1456542007, 2),
"t" : NumberLong(3)
},
"optimeDate" : ISODate("2016-02-27T03:00:07Z"),
"electionTime" : Timestamp(1456541048, 1),
"electionDate" : ISODate("2016-02-27T02:44:08Z"),
"configVersion" : 4,
"self" : true
},
{
"_id" : 3,
"name" : "somehost:30000",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 2070226,
"lastHeartbeat" : ISODate("2016-02-27T03:00:26.859Z"),
"lastHeartbeatRecv" : ISODate("2016-02-27T03:00:25.360Z"
),
"pingMs" : NumberLong(0),
"configVersion" : 4
}
],
"ok" : 1
}
原来的端口号为 27017 的主节点健康标记已为 0(不可用)。
2016-02-27T10:44:02.924+0800 I ASIO [ReplicationExecutor] dropping unhealthy pooled connection to somehost:27017
2016-02-27T10:44:02.924+0800 I ASIO [ReplicationExecutor] after drop, pool was empty, going to spawn some connections
2016-02-27T10:44:02.924+0800 I REPL [ReplicationExecutor] Error in heartbeat request to somehost:27017; HostUnreachable Connection refused
可见尽管仲裁已经放弃了对 27017 的连接,但还是会一直给 27017 发心跳包以待其恢复正常后继续使用。
$ ,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 57,
"optime" : {
"ts" : Timestamp(1456542907, 4),
"t" : NumberLong(3)
},
"optimeDate" : ISODate("2016-02-27T03:15:07Z"),
"lastHeartbeat" : ISODate("2016-02-27T03:16:57.609Z"),
"lastHeartbeatRecv" : ISODate("2016-02-27T03:16:59.124Z"
),
"pingMs" : NumberLong(0),
"syncingTo" : "somehost:27019",
"configVersion" : 4
},
{
"_id" : 1,
"name" : "somehost:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 2071270,
"optime" : {
"ts" : Timestamp(1456542907, 4),
"t" : NumberLong(3)
},
"optimeDate" : ISODate("2016-02-27T03:15:07Z"),
"lastHeartbeat" : ISODate("2016-02-27T03:16:59.207Z"),
"lastHeartbeatRecv" : ISODate("2016-02-27T03:16:57.656Z"
),
"pingMs" : NumberLong(0),
"syncingTo" : "somehost:27019",
"configVersion" : 4
},
{
"_id" : 2,
"name" : "somehost:27019",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 2071271,
"optime" : {
"ts" : Timestamp(1456542907, 4),
"t" : NumberLong(3)
},
"optimeDate" : ISODate("2016-02-27T03:15:07Z"),
"electionTime" : Timestamp(1456541048, 1),
"electionDate" : ISODate("2016-02-27T02:44:08Z"),
"configVersion" : 4,
"self" : true
},
{
"_id" : 3,
"name" : "somehost:30000",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 2071217,
"lastHeartbeat" : ISODate("2016-02-27T03:16:59.205Z"),
"lastHeartbeatRecv" : ISODate("2016-02-27T03:16:55.506Z"
),
"pingMs" : NumberLong(0),
"configVersion" : 4
}
],
"ok" : 1
}
可见 27017 节点已恢复正常,并作为 slave 节点进行服务。仲裁的日志也说明了这个:
2016-02-27T11:16:03.721+0800 I ASIO [NetworkInterfaceASIO-Replication-0] Successfully connected to somehost:27017
2016-02-27T11:16:03.722+0800 I REPL [ReplicationExecutor] Member somehost:27017 is now in state SECONDARY
slave 节点的故障及恢复基本相似与此。