热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

MongoDB数据库的replicasets主从复制同步设置

MongoDB核心开发工程师KristinaChodorow(@kchodorow)最近在她的博客上表示,她会发表一系列关于MongoDBReplicaSets相关的文章,向大家详细的进行一次ReplicaSets的知识培训。其系列文章内容包括下面一些章节:Elections(选举)Creatingaset(创建一
MongoDB核心开发工程师 Kristina Chodorow(@kchodorow) 最近在她的博客上表示,她会发表一系列关于MongoDB Replica Sets 相关的文章,向大家详细的进行一次 Replica Sets 的知识培训。其系列文章内容包括下面一些章节:
Elections(选举)
Creating a set(创建一个replica sets)
Reconfiguring(重新配置)
Syncing(同步)
Initial Sync(初始化同步)
Rollback(数据回滚)
Authentication(权限控制)
Debugging(故障排除)
  本文主要对Replica Sets节点间的同步机制和同步协议进行了深入讲解。
  同步过程
  一个健康的secondary在运行时,会选择一个离自己最近的,数据比自己新的节点进行数据同步。选定节点后,它会从这个节点拉取oplog同步日志,具体流程是这样的:
  1.执行这个op日志
   2.将这个op日志写入到自己的oplog中(local.oplog.rs)
  3.再请求下一个op日志
  如果同步操作在第1步和第2步之间出现问题宕机,那么secondary再重新恢复后,会检查自己这边最新的oplog,由于第2步还没有执行,所以自己这边还没有这条写操作的日志。这时候他会再把刚才执行过的那个操作执行一次。那对同一个写操作执行两次会不会有问题呢?MongoDB在设计oplog时就考虑到了这一点,所以所有的oplog都是可以重复执行的,比如你执行 {$inc:{counter:1}} 对counter字段加1,counter字段在加1 后值为2,那么在oplog里并不会记录 {$inc:{counter:1}} 这个操作,而是记录 {$set:{counter:2}}这个操作。所以无论多少次执行同一个写操作,都不会出现问题。
  w参数
  当我们在MongoDB时执行一个写操作时,默认会直接返回成功,同时也可以通过设置w参数,指定这个写操作同步到几个节点后才返回成功。如下:
db.foo.runCommand({getLastError:1, w:2})
  上面命令就是执行getLastError命令,使其在上一个写操作同步到两个节点上后再返回。不同的客户端可能在写法上不太一样,不过这个功能应该都是有的。对于重要数据,可以考虑采用这样的方式,通过牺牲一部分写性能来提升数据的安全性。

  这个功能是如何实现的呢,primary节点是如何知道数据同步了几份呢?
  在调用上面命令时,实际上MongoDB内部执行了如下的一些流程:
  1.在primary上完成写操作
  2.在primary上记录一条oplog日志,日志中包含一个ts字段,值为写操作执行的时间,比如本例中记为t
  3.客户端调用{getLastError:1, w:2}命令等待primary返回结果
  4.secondary从primary拉取oplog,获取到刚才那一次写操作的日志
  5.secondary按获取到的日志执行相应的写操作
  6.执行完成后,secondary再获取新的日志,其向primary上拉取oplog的条件为{ts:{$gt:t}}
  7.primary此时收到secondary的请求,了解到secondary在请求时间大于t的写操作日志,所以他知道操作在t之前的日志都已经成功执行了
  8.这时候getLastError命令检测到primary与secondary都完成了这次写操作,于是 w:2 的条件满足了,返回给客户端成功
  启动初始化
  当一个新节点启动并加入到现在的Replica Sets中时,这时候新启动的节点会查看自己的oplog,通过一个叫 lastOpTimeWritten 的命令查找到它最近的一条写操作。这个命令你也可以随便在命令行执行:
> rs.debug.getLastOpWritten()
  这个命令会返回一条oplog记录,其中的ts字段就是最近一次写操作的时间了。

  如果你这个节点是全新的,没有数据,那么oplog里也没有数据,这时候节点会选择执行一次全量的同步。本文暂时不对全量同步的方法进行描述。
  选择同步源节点
  Replica Sets中的节点之间总在同步数据,但是他们不是通过传统的一主多从的方式来同步的。MongoDB的策略是选择一个合适的节点作为数据源。
  首先secondary节点会通过ping的时间来确定其它节点与它的距离。时间越长的识为距离越远。然后通过下面方法确定其源节点:
for each member that is healthy:
if member[state] == PRIMARY
add to set of possible sync targets
if member[lastOpTimeWritten] > our[lastOpTimeWritten]
add to set of possible sync targets
sync target = member with the min ping time from the possible sync targets
  对于节点是否healthy的判断,各个版本不同,但是其目的都是找出正常运转的节点。在2.0版本中,它的判断还包括了salve delay这个因素。

  你可以通过运行db.adminCommand({replSetGetStatus:1})命令来查看当前的节点状况,在secondary上运行这个命令,你能看到syncingTo这个字段,这个字段的值就是这个secondary的同步源。(其实名字应该是叫syncingFrom,但是由于版本兼容的原因,沿用了这个错误的名字)
  链式同步结构
  上面对w参数的实现,讲解上比较简单,只讲了w为2的情况,但是当w更大时,由于我们并不是采用一主多从的方式进行同步。所以情况会复杂一些。
  比如我们有节点A,为primary节点,然后B节点为secondary节点,它从A节点同步数据,同时又有secondary节点C,它从同是secondary的B节点同步数据。这样A->B->C之间就形成了一个链式的同步结构。如果我们设定w为3,那么A节点如何能知道C节点已经从B节点同步成功了呢?
  这是通过oplog同步协议来实现的,我们用通俗的语言来解释一下oplog的同步协议。
当C从B同步数据时,C会在协议中对B说:我要从你这同步数据了,如果写操作有w参数的话,我的同步也算上吧。
然后B会回答说:我不是一个primary节点,我会把你的这个计数转到我的同步源上去。
然后B再对A打开一个新的连接,并且对A说:这个连接你就当成是C的吧,也算一个计数在w里。
这时候在A看来,就有两个连接连到他上面,一个是B,一个是虚拟的C,这两个连接都能报告他说完成了同步操作。
  当一个写操作在A上执行后,B首先同步到这个操作的oplog,执行完后会告诉A,我执行完了。然后C同样从B上获取到B的oplog,也执行了这一条写操作,然后他告诉B,我执行完了,B在收到这个响应后,会通过刚才开通的虚拟通道跟A说,我是虚拟的C节点,我也完成写操作了。这时候A就知道,A、B、C三个节点都完成写操作了。w:3的条件满足,然后返回给调用getLastError的客户端,完成这次操作。
  具体三个节点间的连接如下图:
C        B        A
           <====>
  <====>   <---->
  B和A之间有两条通道,双线那条是真正的同步连接,单线那条是一个虚拟连接。
  新功能展望
  上面就是当前的Replica Sets同步的内部实现,在后续这一块还会进行一些新特性的开发。在2.2版本中,我们会提供replSetSyncFrom命令,让用户可以手动设置一个secondary的同步源。使用方法大概是这样:
> db.adminCommand({replSetSyncFrom:"otherHost:27017"})
  敬请期待,thx


推荐阅读
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 本文介绍了新款奇骏的两个让人上瘾的功能,分别是智能互联系统和BOSE音响。通过对新款奇骏的配置和功能进行评测,探讨了这两个新增功能的使用体验和优势。此外,还介绍了新款奇骏的其他配置和改进,如增加的座椅和驾驶辅助系统,以及内饰的舒适性提升。对于喜欢音响的消费者来说,BOSE音响的升级也是一个亮点。最后,文章提到了BOSE音响的数字还原能力,以及7座版无法配备BOSE音响的原因。 ... [详细]
  • 本文介绍了adg架构设置在企业数据治理中的应用。随着信息技术的发展,企业IT系统的快速发展使得数据成为企业业务增长的新动力,但同时也带来了数据冗余、数据难发现、效率低下、资源消耗等问题。本文讨论了企业面临的几类尖锐问题,并提出了解决方案,包括确保库表结构与系统测试版本一致、避免数据冗余、快速定位问题等。此外,本文还探讨了adg架构在大版本升级、上云服务和微服务治理方面的应用。通过本文的介绍,读者可以了解到adg架构设置的重要性及其在企业数据治理中的应用。 ... [详细]
  • 禁止程序接收鼠标事件的工具_VNC Viewer for Mac(远程桌面工具)免费版
    VNCViewerforMac是一款运行在Mac平台上的远程桌面工具,vncviewermac版可以帮助您使用Mac的键盘和鼠标来控制远程计算机,操作简 ... [详细]
  • 本文详细介绍了云服务器API接口的概念和作用,以及如何使用API接口管理云上资源和开发应用程序。通过创建实例API、调整实例配置API、关闭实例API和退还实例API等功能,可以实现云服务器的创建、配置修改和销毁等操作。对于想要学习云服务器API接口的人来说,本文提供了详细的入门指南和使用方法。如果想进一步了解相关知识或阅读更多相关文章,请关注编程笔记行业资讯频道。 ... [详细]
  • 生成对抗式网络GAN及其衍生CGAN、DCGAN、WGAN、LSGAN、BEGAN介绍
    一、GAN原理介绍学习GAN的第一篇论文当然由是IanGoodfellow于2014年发表的GenerativeAdversarialNetworks(论文下载链接arxiv:[h ... [详细]
  • 信息安全等级保护是指对国家秘密信息、法人和其他组织及公民的专有信息以及公开信息和存储、传输、处理这些信息的信息系统分等级实行安全保护,对信息系统中使用的信息安全产品实 ... [详细]
  • 无线认证设置故障排除方法及注意事项
    本文介绍了解决无线认证设置故障的方法和注意事项,包括检查无线路由器工作状态、关闭手机休眠状态下的网络设置、重启路由器、更改认证类型、恢复出厂设置和手机网络设置等。通过这些方法,可以解决无线认证设置可能出现的问题,确保无线网络正常连接和上网。同时,还提供了一些注意事项,以便用户在进行无线认证设置时能够正确操作。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 本文详细介绍了相机防抖的设置方法和使用技巧,包括索尼防抖设置、VR和Stabilizer档位的选择、机身菜单设置等。同时解释了相机防抖的原理,包括电子防抖和光学防抖的区别,以及它们对画质细节的影响。此外,还提到了一些运动相机的防抖方法,如大疆的Osmo Action的Rock Steady技术。通过本文,你将更好地理解相机防抖的重要性和使用技巧,提高拍摄体验。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文详细介绍了华为4GLTE路由器B310的外置天线安装和设置方法。通过连接电源和网线,输入路由器的IP并登陆设置页面,选择手动设置和手动因特网设置,输入ISP提供商的用户名和密码,并设置MTU值。同时,还介绍了无线加密的设置方法。最后,将外网线连在路由器的WAN口即可使用。 ... [详细]
author-avatar
万万558
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有