手动主从切换
方法一:
修改主节点状态
将Primary节点降级为Secondary节点
myapp:PRIMARY> rs.stepDown()
这个命令会让primary降级为Secondary节点,并维持60s,如果这段时间内没有新的primary被选举出来,这个节点可以要求重新进行选举。也可手动指定时间
myapp:PRIMARY> rs.stepDown(30)
冻结Secondary节点
不打算在维护的这段时间内将其它Secondary节点选举为Primary节点,可以在每次Secondary节点上执行freeze命令,强制使它们始终处于Secondary节点状态。
myapp:SECONDARY> rs.freeze(100)
注:只能在Secondary节点上执行
如果要解冻Secondary节点,只需执行
myapp:SECONDARY> rs.freeze()
方法二:优先级设置
思路:
1.为了保证数据的一致性,必须先关闭应用的写服务。
2.提升要升级为Primary节点的Secondary节点的优先级。
arps:PRIMARY> config=rs.conf() //查看当前配置,存入config变量中。
arps:PRIMARY> config.members[2].priority = 3 //修改config变量,第三组成员的优先级为3.
arps:PRIMARY> rs.reconfig(config) //配置生效
修改副本集相关配置
添加节点
myapp:PRIMARY> rs.add("node3:27017") #添加节点
myapp:PRIMARY> rs.add({_id: 3, host: "node3:27017", priority: 0, hidden: true})
rs.addArb("192.168.1.102:27017") #添加仲裁节点
也可以通过配置文件的方式
> cfg={
"_id" : 3,
"host" : "node3:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : true,
"priority" : 0,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
> rs.add(cfg)
删除节点
第一种方式
myapp:PRIMARY> rs.remove("node3:27017")
第二种方式
myapp:PRIMARY> cfg = rs.conf()
myapp:PRIMARY> cfg.members.splice(2,1)
myapp:PRIMARY> rs.reconfig(cfg)
注:执行rs.reconfig并不必然带来副本集的重新选举,加force参数同样如此。
修改节点
将Secondary节点设置为延迟备份节点
cfg = rs.conf()
cfg.members[1].priority = 0
cfg.members[1].hidden = true
cfg.members[1].slaveDelay = 3600
rs.reconfig(cfg)
将Secondary节点设置为隐藏节点
cfg = rs.conf()
cfg.members[0].priority = 0
cfg.members[0].hidden = true
rs.reconfig(cfg)
替换当前的副本集成员
cfg = rs.conf()
cfg.members[0].host = "mongo2.example.net"
rs.reconfig(cfg)
设置副本集节点的优先级
cfg = rs.conf()
cfg.members[0].priority = 0.5
cfg.members[1].priority = 2
cfg.members[2].priority = 2
rs.reconfig(cfg)
优先级的有效取值是0~1000,可为小数,默认为1
注:如果将当前Secondary节点的优先级设置的大于Primary节点的优先级,会导致当前Primary节点的退位。
阻止Secondary节点升级为Primary节点
只需将priority设置为0
cfg = rs.conf()
cfg.members[1].priority = 0
rs.reconfig(cfg)
如何设置没有投票权的Secondary节点
MongoDB限制一个副本集最多只能拥有50个成员节点,其中,最多只有7个成员节点拥有投票权。
之所以作此限制,主要是考虑到心跳请求导致的网络流量,毕竟每个成员都要向其它所有成员发送心跳请求,和选举花费的时间。
从MongoDB 3.2开始,任何priority大于0的节点都不可将votes设置为0
所以,对于没有投票权的Secondary节点,votes和priority必须同时设置为0
cfg = rs.conf()
cfg.members[3].votes = 0
cfg.members[3].priority = 0
cfg.members[4].votes = 0
cfg.members[4].priority = 0
rs.reconfig(cfg)
禁用chainingAllowed
默认情况下,允许级联复制。
即备份集中如果新添加了一个节点,这个节点很可能是从其中一个Secondary节点处进行复制,而不是从Primary节点处复制。
MongoDB根据ping时间选择同步源,一个节点向另一个节点发送心跳请求,就可以得知心跳请求所耗费的时间。MongoDB维护着不同节点间心跳请求的平均花费时间,选择同步源时,会选择一个离自己比较近而且数据比自己新的节点。
如何判断节点是从哪个节点处进行复制的呢?
myapp:PRIMARY> rs.status().members[1].syncingTo
node3:27018
当然,级联复制也有显而易见的缺点:复制链越长,将写操作复制到所有Secondary节点所花费的时间就越长。
可通过如下方式禁用
cfg=rs.conf()
cfg.settings.chainingAllowed=false
rs.reconfig(cfg)
将chainingAllowed设置为false后,所有Secondary节点都会从Primary节点复制数据。
为Secondary节点显式指定复制源
rs.syncFrom("node3:27019")
禁止Secondary节点创建索引
有时,并不需要Secondary节点拥有和Primary节点相同的索引,譬如这个节点只是用来处理数据备份或者离线的批量任务。这个时候,就可以阻止Secondary节点创建索引。
在MongoDB 3.4版本中,不允许直接修改,只能在添加节点时显式指定
myapp:PRIMARY> cfg=rs.conf()
myapp:PRIMARY> cfg.members[2].buildIndexes=false
false
myapp:PRIMARY> rs.reconfig(cfg)
{
"ok" : 0,
"errmsg" : "priority must be 0 when buildIndexes=false",
"code" : 103,
"codeName" : "NewReplicaSetConfigurationIncompatible"
}
myapp:PRIMARY> cfg.members[2].buildIndexes=false
false
myapp:PRIMARY> cfg.members[2].priority=0
0
myapp:PRIMARY> rs.reconfig(cfg)
{
"ok" : 0,
"errmsg" : "New and old configurations differ in the setting of the buildIndexes field for member node3:27017; to make this c
hange, remove then re-add the member", "code" : 103,
"codeName" : "NewReplicaSetConfigurationIncompatible"
}
myapp:PRIMARY> rs.remove("node3:27017")
{ "ok" : 1 }
myapp:PRIMARY> rs.add({_id: 2, host: "node3:27017", priority: 0, buildIndexes:false})
{ "ok" : 1 }
从上述测试中可以看出,如果要将节点的buildIndexes设置为false,必须同时将priority设置为0。