设为首页 收藏本站
查看: 788|回复: 0

[经验分享] mongoDB研究笔记:复制集故障转移机制

[复制链接]

尚未签到

发表于 2015-7-7 12:16:24 | 显示全部楼层 |阅读模式
  上面的介绍的数据同步(http://www.iyunv.com/guoyuanwei/p/3293668.html)相当于传统数据库中的备份策略,mongoDB在此基础还有自动故障转移的功能。在复制集概述那一节提到过心跳"lastHeartbeat"字段,mongoDB就是靠它来实现自动故障转移的。 mongod实例每隔2秒就向其它成员发送一个心跳包以及通过rs.staus()中返回的成员的”health”值来判断成员的状态。如果出现复制集中primary节点不可用了,那么复制集中所有secondary的节点就会触发一次选举操作,选出一个新的primary节点。如上所配置的复制集中如果primary节点宕机了,那么就会选举secondary节点成为primary节点,arbiter节点只是参与选举其它成员成为primary节点,自己永远不会成为primary节点。如果secondary节点有多个则会选择拥有最新时间截的oplog记录或较高权限的节点成为primary节点。oplog记录在前面复制集概述中已经描述过,关于复制集中节点权限配置的问题可在复制集启动的时候进行设置,也可以在启动后重新配置,这里先略过这一点,集中精力讨论故障转移。
  如果是某个secondary节点失败了,只要复制集中还有其它secondary节点或arbiter节点存在,就不会发生重新选举primary节点的过程。
  下面模拟两种失败场景:一是secondary节点的失败,然后过一段时间后重启(时间不能无限期,否则会导致oplog.rs集合严重滞后的问题,需要手动才能同步);二是primary节点失败,故障转移发生。
  先分析第一种情况的测试,当前复制集的配置情况如下:
  (1)rs0:PRIMARY> rs.conf()
  {
  "_id" : "rs0",
  "version" : 3,
  "members" : [
  {
  "_id" : 0,
  "host" : "Guo:40000" //primary节点
  },
  {
  "_id" : 1,
  "host" : "Guo:40001" //secondary节点
  },
  {
  "_id" : 2,
  "host" : "Guo:40002", //arbiter节点
  "arbiterOnly" : true
  }
  ]
  }
  (2)通过Kill掉secondary节点所在的mongod实例,通过rs.status()命令查看复制集状态,secondary节点状态信息如下:
  "_id" : 1,
  "name" : "Guo:40001",
  "health" : 0,
  "state" : 8, //表示成员已经down机
  "stateStr" : "(not reachable/healthy)",
  "uptime" : 0,
  "optime" : {
  "t" : 1376838296,
  "i" : 1
  },
  "optimeDate" : ISODate("2013-08-18T15:04:56Z")
  (3)接着通过primary节点插入一条记录:
  rs0:PRIMARY> db.scores.insert({stuid:2,subject:"english",score:100})
  (4)再次查看复制集状态信息rs.status(),可以看到primary成员节点上oplpog信息如下:
  "optime" : {
  "t" : 1376922730,
  "i" : 1
  },
  "optimeDate" : ISODate("2013-08-19T14:32:10Z"),
  与上面down机的成员节点比较,optime已经不一样,primary节点上要新于down机的节点。
  (5)重新启动Kill掉的节点
  >mongod --config E:\mongodb-win32-i386-2.4.3\configs_rs0\rs0_1.conf
  查询复制集状态信息rs.status(),观看节点"Guo:40001"的状态信息如下:
  "_id" : 1,
  "name" : "GUO:40001",
  "health" : 1,
  "state" : 2,
  "stateStr" : "SECONDARY",
  "uptime" : 136,
  "optime" : {
  "t" : 1376922730, //与上面primary节点一致了
  "i" : 1
  },
  "optimeDate" : ISODate("2013-08-19T14:32:10Z"),
  说明secondary节点已经恢复,并且从primary节点同步到了最新的操作数据。进一步通过查询secondary节点上local数据库上的oplog.rs集合来进行验证,发现多了一条下面这样的记录:
  { "ts" : { "t" : 1376922730, "i" : 1 }, "h" : NumberLong("-451684574732211704"),
  "v" : 2, "op" : "i", "ns" : "students.scores", "o" : { "_id" : ObjectId("52122c
  6a99c5a3ae472a6900"), "stuid" : 2, "subject" : "english", "score" : 100 } }
  这正是在primary节点上插入的记录,再次证明数据确实同步过来了。
  接下来测试第二种情况:
  (1)将primary节点Kill掉。
  查询复制集的状态信息rs.status()
  "name" : "Guo:40000",
  "health" : 0,
  "state" : 8,
  "stateStr" : "(not reachable/healthy)"
  字段"health"的值为0,说明原来的primary节点已经down机了。
  "name" : "Guo:40001",
  "health" : 1,
  "state" : 1,
  "stateStr" : "PRIMARY"
  字段"stateStr"值为"PRIMARY",说明原来secondary节点变成了primary节点。
  (2)在新的primary节点上插入一条记录
  rs0:PRIMARY> db.scores.insert({stuid:3,subject:"computer",score:99})
  (3)重新恢复"Guo:40000"节点(原来的primary节点)
  >mongod --config E:\mongodb-win32-i386-2.4.3\configs_rs0\rs0_0.conf
  再次查看复制集状态rs.status()
  "name" : "Guo:40000",
  "health" : 1,
  "state" : 2,
  "stateStr" : "SECONDARY",
  "uptime" : 33,
  "optime" : {
  "t" : 1376924110,
  "i" : 1
  },
  当"Guo:40000"实例被重新激活后,变成了secondary节点,oplog也被同步成最新的了。说明当primary节点故障时,复制集能自动转移故障,将其中一个secondary节点变为primary节点,读写操作继续在新的primary节点上进行。原来primary节点恢复后,在复制集中变成了secondary节点。
  上面两中情况都得到了验证,但是有一点要注意,mongDB默认情况下只能在primary节点上进行读写操作。对于客户端应用程序来说,对复制集的读写操作是透明的,默认情况它总是在primary节点上进行。 mongoDB提供了很多种常见编程语言的驱动程序,驱动程序位于应用程序与mongod实例之间,应用程发起与复制集的连接,驱动程序自动选择primary节点。当primary节点失效,复制集发生故障转移时,复制集将先关闭与所有客户端的socket连接,驱动程序将返回一个异常,应用程序收到这个异常,这个时候需要应用程序开发人员去处理这些异常,同时驱动程序会尝试重新与primary节点建立连接(这个动作对应用程序来说是透明的)。假如这个时候正在发生一个读操作,在异常处理中你可以重新发起读数据命令,因为读操作不会改变数据库的数据;假如这个时候发生的是写操作,情况就变得微妙起来,如果是非安全模式下的写,就会产生不确定因素,写是否成功不确定,如果是安全模式,驱动程序会通过getlasterror命令知道哪些写操作成功了,哪些失败,驱动程序会返回失败的信息给应用程序,针对这个异常信息,应用程序可以决定怎样处置这个写操作,可以重新执行写操作,也可以直接给用户暴出这个错误。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-84112-1-1.html 上篇帖子: MongoDB与PHP的简单应用 下篇帖子: MongoDB update操作文档
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表