MongoDB 副本集的原理、搭建、应用
这篇写的很详细,http://www.cnblogs.com/zhoujinyi/p/3554010.html
MongoDB 副本集(Replica Set)是有自动故障恢复功能的主从集群,有一个Primary节点和一个或多个Secondary节点组成。
与主从复制不同的是,主从复制中只有一个Master,当Master节点挂掉之后,所有的Slave节点无法自动变为Master,继续提供服务。这时所有的 Slave也就会因连不上Master而无法继续备份数据,直到它再次连到Master。
而副本集中所有的节点都可以成为“活跃”节点(一开始是随机推出的),当当前的活跃节点挂掉之后,集群会立即从其它完好的备份节点中推选出一个节点作为“活跃节点”,整个副本集群不会停止备份服务。
一、环境搭建
1、 准备三套MongoDB的启动配置:(监听不同的端口)
分别使用6666,7777,8888三个端口,如下准备启动文件:
以8888端口为例子,三个文件分别如下:
8888.conf --启用服务端的配置参数
dbpath=D:\MongoData2\8888 --数据库地址,提前建好文件夹
port=8888 --端口
bind_ip=127.0.0.1 --服务器ip
replSet=rs1 --副本集名称
8888mongodb.bat --启动客户端
mongo 127.0.0.1:8888
8888mongodbStartServer.bat --启用服务端
mongod --config 8888.conf
另外7777和6666配置文件类似,只是端口,数据库地址不同,副本集名称写成同一个,表示在同一个集合中
2、运行6666mongodbStartServer.bat,7777mongodbStartServer.bat,8888mongodbStartServer.bat把服务端启动
3、初始化副本集
随便登入任意一台机器的MongoDB执行:因为是全新的副本集所以可以任意进入一台执行;要是有一台有数据,则需要在有数据上执行;要多台有数据则不能初始化。
比如启动8888mongodb.bat ,启动8888客户端,依次做如下输入如下命令:
>use admin
>config={_id:"rs1",members:[ {_id:0,host:"localhost:6666","priority":1}, {_id:1,host:"localhost:7777","priority":1}, {_id:2,host:"localhost:8888","priority":1} ]}
rs.initiate(config);
"_id": 副本集的名称
"members": 副本集的服务器列表
"_id": 服务器的唯一ID
"host": 服务器主机
"priority": 是优先级,默认为1,优先级0为被动节点,不能成为活跃节点。优先级不位0则按照有大到小选出活跃节点。
"arbiterOnly": 仲裁节点,只参与投票,不接收数据,也不能成为活跃节点。
4、设置成功,打开3个客户端,可以看到:
三个副本中,有一个是PRIMARY副本节点,另两个是SECONDARY副本节点,如果把主副本服务关掉,目前是7777端口的服务是primary副本节点
这时候,剩下两个副本,会选择一个做Primary节点,另一个做SECONDARY节点,这时候选择了8888端口的服务作为Primary节点
说明:在PRIMARY节点故障情况下,SECONDARY节点也切换成功了。
二、维护操作
1、增加一个节点
首先需要启动一个服务端,并且需要增加replSet参数,比如,我需要在上述三个节点中再增加一个5555端口的节点,首先配置
dbpath=D:\MongoData2\5555 port=5555 bind_ip=127.0.0.1 replSet=rs1
然后启动服务端
然后把节点添加到上述副本集中,在上面三个客户端中随便哪个中执行如下语句:
rs.add("127.0.0.1:5555")
这时候可以使用rs.status()去查看副本集状态:
2、删除节点:
rs.remove("127.0.0.1:5555")
3、查看副本集状态
rs.status()
注意:
所有的Secondary都宕机、或则副本集中只剩下一个节点,则该节点只能为Secondary节点,也就意味着整个集群智能进行读操作而不能进行写操作,当其他的恢复时,之前的primary节点仍然是primary节点。
当某个节点宕机后重新启动该节点会有一段的时间(时间长短视集群的数据量和宕机时间而定)导致整个集群中所有节点都成为secondary而无法进行写操作(如果应用程序没有设置相应的ReadReference也可能不能进行读取操作)。
官方推荐的最小的副本集也应该具备一个primary节点和两个secondary节点。两个节点的副本集不具备真正的故障转移能力。
三、应用配置
1、手动切换Primary节点到自己给定的节点
上面已经提到过了优先集priority,因为默认的都是1,所以只需要把给定的服务器的priority加到最大即可。
比如现在7777端口的服务为PRIMARY 节点,如果要使得5555节点称为PRIMARY节点,只要把5555节点的priority设置为最高,比如设置为2,依次执行如下命令:
cfg=rs.conf() --获取配置
cfg.members[3].priority=2 --修改members中priority配置,索引值从0开始
rs.reconfig(cfg) --重新加载配置文件,强制了副本集进行一次选举,优先级高的成为Primary。在这之间整个集群的所有节点都是secondary
这时候4个members中最后一个,端口5555的成为了PRIMARY节点
2、添加仲裁节点
把8888端口的节点删除,然后添加为仲裁节点,该节点不参与投票,不能转变成Secondary节点
rs.addArb("127.0.0.1:8888")
3、读写分离
主库,从库都支持读操作,但是,默认情况下,读数据也是读取主库数据。
MongoDB副本集对读写分离的支持是通过Read Preferences特性进行支持的,这个特性非常复杂和灵活。
应用程序驱动通过read reference来设定如何对副本集进行读取操作,默认的,客户端驱动所有的读操作都是直接访问primary节点的,从而保证了数据的严格一致性。
支持五种的read preference模式:官网说明
primary 主节点,默认模式,读操作只在主节点,如果主节点不可用,报错或者抛出异常。 primaryPreferred 首选主节点,大多情况下读操作在主节点,如果主节点不可用,如故障转移,读操作在从节点。 secondary 从节点,读操作只在从节点, 如果从节点不可用,报错或者抛出异常。 secondaryPreferred 首选从节点,大多情况下读操作在从节点,特殊情况(如单主节点架构)读操作在主节点。 nearest 最邻近节点,读操作在最邻近的成员,可能是主节点或者从节点,关于最邻近的成员请参考
注意:2.2版本之前的MongoDB对Read Preference支持的还不完全,如果客户端驱动采用primaryPreferred实际上读取操作都会被路由到secondary节点。
因为读写分离是通过修改程序的driver的,故这里就不做说明,具体的可以参考这篇文章或则可以在google上查阅。
参考资料:
l