MongoDB之副本集
1. 副本集架构

副本集是一组保持相同数据集的mongodb实例,包含多个数据节点和一个可选的仲裁节点。
数据节点:主节点和从节点
主节点:接收所有的写操作,通过oplog记录所有在主节点让数据发生改变的操作
从节点:复制主节点的oplog日志信息,并在自己的节点上应用这些oplog
仲裁节点:不维护数据集,目的是响应其它成员的心跳和选举请求。仲裁节点永远只是仲裁节点
2. 自动故障转移

主节点连续10秒无法和其它节点通信时,从库将发生选举,在从库中选出一个库作为新的主库。第一个发起选举并且获得了大多数成员投票的从节点,将成为主节点。
3. 副本集成员状态

4. 副本集原理
Secondary初次同步数据时,先进行init sync操作,从Primary(或其他数据更新的Secondary)同步全量数据,然后不断通过tailable cursor从primary的local.oplog.rs集合里查询最新的oplog并应用到自身
init sync的过程:
1. T1时间,从Primary同步所有数据库的数据(local除外),通过listDatabases+listCollections+cloneCollection命令组合完成,假设T2时间完成所有操作
2. 从primary应用所有的oplog
3. 根据primary各集合的index设置,在secondary上为相应集合创建index

5. 成员配置选项
1. 仲裁者
只参与投票,不能被选为Primary,并且不从Primary同步数据
本身不存储数据
优先级为0
2. 优先级
优先级取值范围0-100,,0为永远不能成为主节点
优先级越大越有机会成为主节点
3. 隐藏节点
Hidden节点不能被选为主节点,并且对Driver不可见
使用Hidden节点做一些数据备份,离线计算的任务,不影响副本集服务
4. 延迟备份节点
必须是备份节点,并且其数据落后于Primary一段时间,可配置
5. 回滚过程
当Primary宕机时,如果有数据未同步到Secondary,当primary重新加入时,如果新的primary已经发生了写操作,则旧primary需要回滚部分操作,以保证数据集与新的primary一致
旧primary将回滚的数据写到单独的rollback目录下,数据库管理员可根据需要使用mongorestore进行恢复
6. oplog
1. oplog介绍
oplog是一个特殊的固定集合,它保存了数据库中所有的数据变化记录
mongodb在主节点应用数据库操作,然后在主节点使用oplog记录操作,从节点异步复制并应用这些操作
所有副本集成员都在local.oplog.rs集合中包含一个oplog的副本
2. oplog大小

默认最大50G
可以在配置文件中指定oplog大小,使用oplogSizeMB
也可以实时更改使用命令rep!SetResizeOplog,无需重新启动mongodb进程(3.6之后特性,旧版本还需要停库)
2. oplog过滤
查询oplog时间大于xx的对某个集合的删除操作
db.oplog.rs.find({ns:"库名.集合名",op:"d","ts":{$gte:Timestamp(1111111,0)}}).count()
ts 操作发生的时间
op 操作的类型
ns 操作的namespace
7. 副本集的数据复制
1. 新成员的初始同步
过程如下:
1. 会复制除local库外的所有数据库。在复制期间,mongod扫描每个源数据库中的每个集合,并把它们进行复制
2. 根据源数据库的oplog,将所有更改应用于数据集,mongod在应用这些数据时会变更自身的状态。初步同步完成后,成员状态从startup2转换到secondary
初始化同步中改集合名
如果初始化过程中源的集合名称已更改,则目标成员的初始化同步将失败并重新启动以避免数据损坏
2. 已有成员之间的持续复制
将oplog从其源同步中复制,并在异步过程中应用这些操作
secondary根据ping时间和其它成员复制状态的变化自动选择同步源
secondary避免从隐藏节点和延迟节点同步
8. 副本集的选举
1. 复制协议版本变更
从mongodb3.2起,使用protocolVersion1,以减少副本集故障转移时间
2. 心跳检测
副本集成员每2秒发送一次心跳,如果10秒内没有返回,则其他成员将没有返回心跳信息的成员标记为不可访问
3. 节点优先级
4. 投票节点
赞成票1
否决票-10000
无投票权的成员必须配置priority为0
priority大于0的成员其vote必须配置为1
5. 非投票节点
副本集最多可以有50个成员,只能有7个有投票权的成员
没有投票权的成员必须配置priority为0
9. 副本集环境搭建
1. 环境结构

在三台服务器分别安装mongodb,并配置环境变量
export MONGO_HOME=/usr/local/mongodb export PATH=$PATH:$MONGO_HOME/bin
2. 配置文件
在三台服务器的配置文件中添加内容:
#指定日志路径
systemLog: destination: file logAppend: true path: /usr/local/mongodb/logs/mongodb.log #指定数据存储路径 storage: dbPath: /usr/local/mongodb/db journal: enabled: true #是否以守护进程方式运行 processManagement: fork: true # fork and run in background #指定网络配置 net: port: 16535
maxIncomingConnections: 10240 #指定最大连接数 bindIp: 0.0.0.0 # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.
#配置验证 #security: #operationProfiling: #配置副本信息 replication: oplogSizeMB: 2048 replSetName: zhenpin
3. 配置副本集
修改完配置文件后,启动三台服务器的mongodb实例。
在任意一台服务器上,登录到mongodb,然后执行:
config={
"_id":"zhenpin",members:[{_id:0,host:"192.168.1.231:16535"},
{_id:1,host:"192.168.1.232:16535"},{_id:2,host:"192.168.1.233:16535"} ] }
然后执行一下初始化,使配置生效。rs.initiate(config)
4. 初始化完成以后,查看一下副本集复制状态
1. 使用命令rs.status();
{
"set" : "zhenpin", 副本集名称
"date" : ISODate("2019-08-14T08:05:26.925Z"), 格林威治时间
"myState" : 1,
"term" : NumberLong(12),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1565769920, 1),
"t" : NumberLong(12)
},
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1565769920, 1),
"t" : NumberLong(12)
},
"appliedOpTime" : {
"ts" : Timestamp(1565769920, 1),
"t" : NumberLong(12)
},
"durableOpTime" : {
"ts" : Timestamp(1565769920, 1),
"t" : NumberLong(12)
}
},
"lastStableCheckpointTimestamp" : Timestamp(1565769880, 1),
"members" : [
{
"_id" : 0,
"name" : "192.168.1.232:16535",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 46124,
"optime" : {
"ts" : Timestamp(1565769920, 1),
"t" : NumberLong(12)
},
"optimeDurable" : {
"ts" : Timestamp(1565769920, 1),
"t" : NumberLong(12)
},
"optimeDate" : ISODate("2019-08-14T08:05:20Z"),
"optimeDurableDate" : ISODate("2019-08-14T08:05:20Z"),
"lastHeartbeat" : ISODate("2019-08-14T08:05:26.724Z"),
"lastHeartbeatRecv" : ISODate("2019-08-14T08:05:25.217Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.1.231:16535",
"syncSourceHost" : "192.168.1.231:16535",
"syncSourceId" : 1,
"infoMessage" : "",
"configVersion" : 1
},
{
"_id" : 1,
"name" : "192.168.1.231:16535",
"health" : 1,
"state" : 1, 1表示primary
"stateStr" : "PRIMARY",
"uptime" : 80854,
"optime" : {
"ts" : Timestamp(1565769920, 1),
"t" : NumberLong(12)
},
"optimeDate" : ISODate("2019-08-14T08:05:20Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1565723805, 1),
"electionDate" : ISODate("2019-08-13T19:16:45Z"),
"configVersion" : 1,
"self" : true, 只出现在执行rs.status()函数的成员信息中
"lastHeartbeatMessage" : ""
},
{
"_id" : 2,
"name" : "192.168.1.233:16535",
"health" : 1, 1表示server正常,0表示宕机
"state" : 2, 2表示secondary,state是内部的叫法
"stateStr" : "SECONDARY",
"uptime" : 79976, 从成员可到达一直到现在经历的时间
"optime" : {
"ts" : Timestamp(1565769920, 1),
"t" : NumberLong(12)
},
"optimeDurable" : {
"ts" : Timestamp(1565769920, 1),
"t" : NumberLong(12)
},
"optimeDate" : ISODate("2019-08-14T08:05:20Z"),
"optimeDurableDate" : ISODate("2019-08-14T08:05:20Z"),
"lastHeartbeat" : ISODate("2019-08-14T08:05:26.762Z"),
"lastHeartbeatRecv" : ISODate("2019-08-14T08:05:26.790Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.1.231:16535", 表示从哪个节点做同步
"syncSourceHost" : "192.168.1.231:16535",
"syncSourceId" : 1,
"infoMessage" : "",
"configVersion" : 1
}
],
"ok" : 1,
"operationTime" : Timestamp(1565769920, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1565769920, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
2. rs.printReplicationInfo() 查看副本集的oplog信息
zhenpin:PRIMARY> rs.printReplicationInfo() configured oplog size: 2048MB log length start to end: 5349779secs (1486.05hrs) oplog first event time: Thu Jun 13 2019 18:38:52 GMT+0800 (CST) oplog last event time: Wed Aug 14 2019 16:41:51 GMT+0800 (CST) now: Wed Aug 14 2019 16:41:58 GMT+0800 (CST)
3. rs.printSlaveReplicationInfo() 查看副本集的从库状态信息
zhenpin:PRIMARY> rs.printSlaveReplicationInfo()
source: 192.168.1.232:16535
syncedTo: Wed Aug 14 2019 16:51:21 GMT+0800 (CST)
0 secs (0 hrs) behind the primary
source: 192.168.1.233:16535
syncedTo: Wed Aug 14 2019 16:51:21 GMT+0800 (CST)
0 secs (0 hrs) behind the primary 落后主库的时间
5. 增加或删除一个副本集成员
1. 增加
rs.add("192.168.1.234:16535") 添加一个成员
rs.addArb("192.168.1.234:16535") 添加一个仲裁
2. 删除
rs.remove("192.168.1.234:16535")
6. 查看刷新副本集配置
1. 查看
rs.conf()
2. 刷新
rs.reconfig(config)
7. 修改副本集配置
在主库执行
config=rs.conf()
config.members[2].priority=0 修改第三个节点的优先级
config.members[2].hidden=true 修改第三个节点为隐藏节点
config.members[2].slaveDelay=21600 修改第三个节点的延迟时间,单位为秒

浙公网安备 33010602011771号