官方副本集配置项
{
_id: ,
version: ,
protocolVersion: ,
writeConcernMajorityJournalDefault: ,
configsvr: ,
members: [
{
_id: ,
host: ,
arbiterOnly: ,
buildIndexes: ,
hidden: ,
priority: ,
tags: ,
slaveDelay: ,
votes:
},
…
],
settings: {
chainingAllowed : ,
heartbeatIntervalMillis : ,
heartbeatTimeoutSecs: ,
electionTimeoutMillis : ,
catchUpTimeoutMillis : ,
getLastErrorModes : ,
getLastErrorDefaults : ,
replicaSetId:
}
}
配置如下
systemLog:
destination: file
logAppend: true
path: /data/mongodb/mongoconf/log/mongoconf.log
storage:
dbPath: /data/mongodb/mongoconf/data
journal:
enabled: true
wiredTiger:
engineConfig:
cacheSizeGB: 1
processManagement:
fork: true
net:
port: 31000
bindIp: 10.0.0.20
maxIncomingConnections: 20000
replication:
replSetName: csReplSet
在已存在的副本集中添加成员
- 成员都按上面的配置,并启动,可能会出现所有成员都为:primary
- 如果出现以上问题,则删除配置中的data目录,然后重启
- rs.initiate() 方法初始化一台,其状态从 other 变为 primary
- 在其它成员都启动后,使用 rs.add() 命令动态添加成员
- rs.addArd() 添加仲裁成员
- rs.status() 查看当前副本集的状态
- rs.isMaster() 查看当前副本集中的 primary 是谁
问题集锦:
rs.add({host:"192.168.100.12:27017"})
# 添加普通的副本集成员,报错,没有仲裁人员即:副本集成员少于3个,无法触发选举,添加失败
# 报错: Quorum check failed because not enough voting nodes responded;
required 2 but only the following 1 voting nodes responded: MongodbServer1:27017;
the following nodes did not respond affirmatively:
MongodbServer2:27017 failed with Received heartbeat from member with the same member ID as ourself: 0
rs.add({host:"192.168.100.12:27017", priority:0, votes:0})
# 添加没有优先级与投票权的成员
# 结果状态为: "stateStr" : "(not reachable/healthy)",
# 错误信息为: "lastHeartbeatMessage" : "Error connecting to 192.168.100.12:27017 :: caused by :: No route to host"
# 解决: telnet 192.168.100.12 27017 不通
# centos7 默认开启了防火墙, systemctl [status|stop] firewalld
如果被添加的实例,原生已经启动成了 primary ,也会报错如下
报错: "lastHeartbeatMessage" : "replica set IDs do not match, ours: 5cc4547e7ccc7e815bcc6e4a; remote node's: 5cc457fa182716a747d773a9"
解决:
确保要 新添加的成员没有客户端链接
如果已经有客户端链接了,退出,然后清除其 data 目录的数据,再重新启动就成功了
rs.add({host:"MongodbServer3:27017", priority:0, votes:1, arbiterOnly:true})
添加仲裁节点或者从节点,都需要其不是其它副本集的任何角色
即: 一个节点,只能在一个副本集中担任一种角色
rs.add({host:"MongodbServer4:27017", priority:1, votes:2})
已存在的副本集中,添加新成员,并指定优先组与投票数
报错如下:
votes field value is 2 but must be 0 or 1
rs.config().members
[
{
"_id" : 0,
"host" : "MongodbServer1:27017",
"arbiterOnly" : false, # 仲裁
"buildIndexes" : true, # 创建索引
"hidden" : false, # 隐藏节点
"priority" : 1, # 优先级
"tags" : {},
"slaveDelay" : NumberLong(0), # 同步延迟
"votes" : 1 # 投票数
}
动态修改配置:
foo:PRIMARY> var cf = rs.config()
foo:PRIMARY> cf.members[1]
{
"_id" : 1,
"host" : "MongodbServer2:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 0,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 0
}
foo:PRIMARY> cf.members[1].votes=1
1
foo:PRIMARY> cf.members[1].priority=1
1
foo:PRIMARY> rs.reconfig(cf) # 刷新配置项
{
"ok" : 1,
"operationTime" : Timestamp(1566966181, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1566966181, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
副本集-链接地址:
mongodb://mongodbserver1:27017,mongodbserver2:27017,mongodbserver4:27017
// 链接地址中写了三个主机的地址,由 MongoDbServer 自动去确定要把查询命令发送到哪一台服务器
// 测试:1 主, 2、4 从 ;查询正常
// 测试:1 停止MongoDb, 2 主,4 从 ;查询正常
// 测试:1 停止,2 停止,4 并没有升为主,所有查询失败
// 测试: 1 主,1从,1仲裁,当从停止时,1主变成了1从,只提供查询,无法写入
// 当集群中的成员,只有一个仲裁与从机时,从机并不会被选举为主,来提供写入服务,查询服务可以正常,前提是在链接地址指定到从机读取数据,参考 MongoDb链接字符串,如下
mongodb://mongodbserver1:27017,mongodbserver2:27017,mongodbserver4:27017/?replicaSet=foo&readPreference=secondary
1主,1从,1仲裁
当从下线后,主却变成了从 ??? 相当于只提供查询服务,不再提供写入服务
// 当集群中的成员,只有一个仲裁与从机时,从机并不会被选举为主,来提供写入服务,查询服务可以正常,前提是在链接地址指定到从机读取数据,参考 MongoDb链接字符串,如下
mongodb://mongodbserver1:27017,mongodbserver2:27017,mongodbserver4:27017/?replicaSet=foo&readPreference=secondary
当一个链接里面,有读有写的时候
如果在链接中指定了 从机 读取,只要有一个主 | 没有主,但有至少一个从机,都能读取成功
但是 如果集群中没有主,则写入肯定失败,会返回类似如下的错误信息:
server selection error: server selection timeout
current topology: Type: ReplicaSetNoPrimary
Servers:
Addr: mongodbserver1:27017, Type: Unknown, State: Connected, Average RTT: 0, Last error: dial tcp 192.168.100.11:27017: connectex: No connection could be made because the target machine actively refused it.
Addr: mongodbserver2:27017, Type: Unknown, State: Connected, Average RTT: 0, Last error: dial tcp 192.168.100.12:27017: connectex: No connection could be made because the target machine actively refused it.
Addr: mongodbserver4:27017, Type: RSSecondary, State: Connected, Average RTT: 500000
Addr: mongodbserver3:27017, Type: RSArbiter, State: Connected, Average RTT: 500100
参考链接地址:
mongodb://mongodbserver1:27017,mongodbserver2:27017,mongodbserver4:27017/?replicaSet=foo&readPreference=secondary
其中参数: readPreference 还可以使用:secondaryPreferred [https://docs.mongodb.com/manual/reference/read-preference/#secondaryPreferred]