MongoDB副本集详解2-数据同步

本人博客同步发表,排版更佳

数据同步

Mongodb副本集里的Secondary会从Primary上同步数据,以保持副本集所有节点的数据保持一致。MongoDB副本集数据同步主要包含2个步骤:

  1. init sync 可以理解为全量同步
  2. oplog sync(replication)追同步源的oplog,可以理解为增量同步

新加入的Secondary先通过init sync同步Primary上的全量数据,再通过oplog sync不断重放Primary上的oplog同步增量数据。


数据同步过程

init sync

Secondary节点当出现如下状况时,需要先进行全量同步

  1. oplog为空
  2. local.replset.minvalid集合里_initialSyncFlag字段设置为true
  3. 内存标记initialSyncRequested设置为true

这3个场景分别对应

  1. 新节点加入,无任何oplog,此时需先进性initial sync
  2. initial sync开始时,会主动将_initialSyncFlag字段设置为true,正常结束后再设置为false;如果节点重启时,发现_initialSyncFlag为true,说明上次全量同步中途失败了,此时应该重新进行initial sync
  3. 当用户发送resync命令时,initialSyncRequested会设置为true,此时会重新开始一次initial sync

intial sync流程

  1. 全量同步开始,设置minvalid集合的_initialSyncFlag
  2. 获取同步源上最新oplog时间戳为t1
  3. 全量同步集合数据,local库除外(耗时)
  4. 获取同步源上最新oplog时间戳为t2
  5. 重放[t1, t2]范围内的所有oplog
  6. 获取同步源上最新oplog时间戳为t3
  7. 重放[t2, t3]范围内所有的oplog
  8. 建立集合所有索引 (耗时)
  9. 获取同步源上最新oplog时间戳为t4
  10. 重放[t3, t4]范围内所有的oplog
  11. 全量同步结束,清除minvalid集合的_initialSyncFlag

oplog sync(replication)

initial sync结束后,Secondary会建立到Primary上local.oplog.rs的tailable cursor,不断从Primary上获取新写入的oplog,并应用到自身。

oplog

Primary与Secondary之间通过oplog来同步数据,Primary上的写操作完成后,会向特殊的 local.oplog.rs 特殊集合写入一条oplog,Secondary不断的从Primary取新的oplog并应用。

因oplog的数据会不断增加,local.oplog.rs被设置成为一个 capped集合 ,当容量达到配置上限时,会将最旧的数据删除掉。另外考虑到oplog在Secondary上可能重复应用,oplog必须具有幂等性,即重复应用也会得到相同的结果。

如下oplog的格式,包含ts、h、op、ns、o等字段

{ 
    "ts" : Timestamp(1521169114, 4), 
    "t" : NumberLong(11), 
    "h" : NumberLong(-2875196737885853602), 
    "v" : NumberInt(2), 
    "op" : "i", 
    "ns" : "testdb.table3", 
    "ui" : BinData(4, "A0pnjSbATe+O+H51myfqwQ=="), 
    "wall" : ISODate("2018-03-16T02:58:34.156+0000"), 
    "o" : {
        "_id" : ObjectId("5aab32dc51382146343c0b03"), 
        "id" : NumberInt(3), 
        "type" : "database3", 
        "test" : "testval3", 
        "name" : "name3"
    }
}
  • ts: 操作时间,当前timestamp + 计数器,计数器每秒都被重置
  • h:操作的全局唯一标识
  • v:oplog版本信息
  • op:操作类型
    • i:插入操作
    • u:更新操作
    • d:删除操作
    • c:执行命令(如createDatabase,dropDatabase)
    • n:空操作,特殊用途
  • ns:操作针对的集合
  • o:操作内容,如果是更新操作
  • o2:操作查询条件,仅update操作包含该字段

oplog sync过程

Tailable cursor每次会获取到一批oplog,Secondary采用多线程重放oplog以提高效率,通过将oplog按照所属的namespace进行分组,划分到多个线程里,保证同一个namespace的所有操作都由一个线程来replay,以保证统一namespace的操作时序跟primary上保持一致(如果引擎支持文档锁,只需保证同一个文档的操作时序与primary一致即可)。

  1. producer thread,这个线程不断的从同步源上拉取oplog,并加入到一个BlockQueue的队列里保存着。
  2. replBatcher thread,这个线程负责逐个从producer thread的队列里取出oplog,并放到自己维护的队列里。
  3. sync线程将replBatcher thread的队列分发到默认16个replWriter线程,由replWriter thread来最终重放每条oplog。
  • 拉取oplog是单线程进行,所以设计上producer thread只干一件事。
  • oplog重放时,要保持顺序性,而且遇到createCollection、dropCollection等DDL命令时,这些命令与其他的增删改查命令是不能并行执行的,而这些控制就是由replBatcher来完成的。
  • 同一个namespace的所有操作都由一个线程来replay,以保证统一namespace的操作时序跟primary上保持一致

同步场景分析

  1. 副本集初始化

    • 初始化选出Primary后,此时Secondary上无有效数据,oplog是空的,会先进行initial sync,然后不断的应用新的oplog
  2. 新成员加入

    • 因新成员上无有效数据,oplog是空的,会先进行initial sync,然后不断的应用新的oplog
  3. 有数据的节点加入

    有数据的节点加入有如下情况:

    • 该节点与副本集其他节点断开连接,一段时间后恢复
    • 该节点从副本集移除(处于REMOVED)状态,通过replSetReconfig命令将其重新加入

    此时,如果该节点最新的oplog时间戳,比所有节点最旧的oplog时间戳还要小,该节点将找不到同步源,会一直处于RECOVERING而不能服务;反之,如果能找到同步源,则直接进入replication阶段,不断的应用新的oplog。

    因oplog太旧而处于RECOVERING的节点目前无法自动恢复,需人工介入处理(故设置合理的oplog大小非常重要),最简单的方式是发送resync命令,让该节点重新进行initial sync。

其他

oplog大小

默认下,oplog大小会占用64位的实例5%的可用磁盘空间,在一些场景下oplog太小会导致同步失败等问题。动态修改oplog大小参考如下方法:

db.runCommand({collMod: "oplog.rs", maxSize: 1024000000})

参考链接

http://www.mongoing.com/archives/2369
http://www.mongoing.com/archives/3076

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  • feisky云计算、虚拟化与Linux技术笔记posts - 1014, comments - 298, trac...
    不排版阅读 3,813评论 0 5
  • 1、副本集/复制集: mongo副本集/复制集是mongo高可用性特征之一,是有自动故障恢复功能的主要集群。由一个...
    Zhang21阅读 1,409评论 0 3
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,596评论 18 139
  • 对待亲密关系会想当然,对待父母亲人熟悉的人也是如此。 我好多次都犯过这样的事情,事后被妈妈嫌弃不断。比如,妈妈让我...
    小琴晴阅读 305评论 0 2
  • 格雷戈·麦吉沃恩是THIS公司创始人,该公司致力于帮助个人和企业将80%的时间用在正确的事情上,免受琐事的困扰。公...
    环盈阅读 247评论 0 1