免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1604 | 回复: 0
打印 上一主题 下一主题

[MongoDB] MongoDB原理:复制集状态同步机制 [复制链接]

求职 : Linux运维
论坛徽章:
203
拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:57:092015小元宵徽章
日期:2015-03-06 15:58:182015年亚洲杯之约旦
日期:2015-04-05 20:08:292015年亚洲杯之澳大利亚
日期:2015-04-09 09:25:552015年亚洲杯之约旦
日期:2015-04-10 17:34:102015年亚洲杯之巴勒斯坦
日期:2015-04-10 17:35:342015年亚洲杯之日本
日期:2015-04-16 16:28:552015年亚洲杯纪念徽章
日期:2015-04-27 23:29:17操作系统版块每日发帖之星
日期:2015-06-06 22:20:00操作系统版块每日发帖之星
日期:2015-06-09 22:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-04-26 20:06 |只看该作者 |倒序浏览
MongoDB复制集(3.0版本)之间通过心跳信息来同步成员的状态信息,每个节点会周期性的向复制集内其它的成员发送心跳信息来获取状态,如rs.status()看到的复制集状态信息。

一次心跳请求分3个阶段 (主动发起心跳请求的节点称为源,接受到心跳请求的成为目标)

源向目标发送心跳请求
目标处理心跳请求,并向源发送应答
源接受到心跳应答,更新目标节点状态
接下来将介绍这3个阶段里的主要状态同步逻辑

阶段1

默认配置下,复制集的节点每隔2s会向其他成员发送一次心跳请求,即发送replSetHeartbeat命令请求,心跳请求的内容类似如下(通过mongosniff抓包获取),主要包含replSetName、发送心跳的节点地址、复制集版本等。

command: replSetHeartbeat database: admin metadata: { $replData: 1 } commandArgs: { replSetHeartbeat: "mongo-9552", pv: 1, v: 22, from: "10.101.72.137:9552", fromId: 3, checkEmpty: false }
阶段2

复制集成员收到心跳请求后,就开始处理请求,并将处理的结果回复给请求的节点。

如果自身不是复制集模式、或复制集名称不匹配,则返回错误应答
如果源节点的复制集配置(rs.conf()的内容)版本比自己低,则将自身的配置加入到心跳应答消息里
将节点自身的oplog及其他状态信息等加入到心跳应答消息
如果自身是未初始化状态,则立即向源节点发送心跳请求,以更新复制集配置

commandReply: { ok: 1.0, time: 1460705698, electionTime: new Date(6273289095791771649), e: true, rs: true, state: 1, v: 22, hbmsg: "", set: "mongo-9552", opTime: new Date(6272251740930703361) } metadata: { $replData: { term: -1, lastOpCommitted: { ts: Timestamp 1460372410000|1, t: -1 }, lastOpVisible: { ts: Timestamp 0|0, t: -1 }, configVersion: 22, primaryIndex: 2, syncSourceIndex: -1 } }
阶段3

阶段3是最主要的处理部分,节点收到心跳应答后,会根据应答消息来更新对端节点的状态,并根据最终的状态确定是否需要进行重新选举。

收到心跳应答时,如果是错误应答(心跳消息超时未应答相当于收到了错误应答),则
如果当前重试次数 <= kMaxHeartbeatRetries(默认为2),并且上一次发送心跳在kDefaultHeartbeatTimeoutPeriod(默认为10)时间内,则立即发送下一次心跳
当失败次数超过kMaxHeartbeatRetries,或者上一次心跳时间到现在超过kDefaultHeartbeatTimeoutPeriod,则认为节点down
如果对端的复制集版本比自己高,则更新自己的配置并持久化到local数据库中
根据应答消息更新对端的状态信息
如果自身是主节点,当发现有优先级更高的节点可被选为主,则主动降级
如果其他是主节点,但自身有更高的优先级并可被选为主,则会主动要求主节点降级(目前这个逻辑实现有bug,主要靠主节点主动降级来保证优先级最高的节点最终会变成主, https://jira.mongodb.org/browse/SERVER-23630
如果当前没有主节点,则主动发起新的选举,当得到大多数节点同意后,即可选出新的主节点
总的来说,MongoDB通过心跳来同步节点间信息并触发选举,最终将复制集达到统一的状态,但过程的正确性没有理论依据,MongoDB-3.2版本里,使用了新版本的复制集通信协议,改用raft来选举,能进一步降低故障发现恢复时间
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP