mongodb副本集的基础概念和各种机制

     从一开始我们就在讲如何使用一台服务器.一个mongod服务器进程,如果只用做学习和开发,这是可以的,但如果在生产环境中,这是很危险的,如果服务器崩溃了怎么办?数据库至少要一段时间不可用,如果是硬件出现问题呢?可能需要将数据迁移到另一台机器上.使用复制供功能可以将数据副本保存在多台服务器上,建议在生产环境中都要使用,使用mongodb的复制功能,即使一台或者多台服务器出错,也可以保证应用程序的正常运行和数据安全.
     MongoDB的数据库复制增加了冗余,确保了高可用性,简化了管理任务如备份,并且增加了读能力。

     在mongodb中 创建一个副本集之后就可以使用复制功能了,副本集是一组服务器,其中一个主服务器(primary[ˈpraɪˌmɛri, -məri]),用于处理客户端请求,还有多个备份服务器(secondary[ˈsɛkənˌdɛri]),用于保存主服务器的数据副本,如果主服务器崩溃了,备份服务器会自动将其中成员升级为新的主服务器,副本集中一个很重要的概念就是大多数(majority[məˈdʒɔrɪti, -ˈdʒɑr-]) 选择主节点时需要由大多数决定 主节点只有在得到大多数成员支持时才能继续作为主节点 写操作被复制到大多数成员时这个写操作是安全的,这里的大多数被定义为副本中一半以上的成员,

     一个副本集可以最多支持12个成员,但是只有7个成员可以参与投票。
 
故障切换恢复
     副本集能够自动进行故障切换恢复。如果primary掉线或者无反应且多数的副本集成员能够相互连接,则选出一个新的primary。
在多数情况下,当primary宕机、不可用或者是不适合做primary时,在没有管理者干预的几秒后会进行故障切换。
如果MongoDB部署没有如预期那样进行故障切换,则可能是下面的问题:
  • 剩余的成员个数少于副本集的一半
  • 没有成员有资格成为primary
Rollback
 
     多数情况下,回滚操作可以优雅的对不能进行故障切换恢复的情况进行恢复。
     Rollbacks操作发生在primary处理写操作,但其它成员没有成功的进行复制之前primary掉线时。当先前的primary恢复工作,开始复制时,则表现出rollback。如果操作复制到其它成员,该成员可用,并且可以和大多数的副本集连接,则没有rollback。
     Rollbacks删除了那些没有进行复制的操作,以保证数据集的一致性。
选举机制
     当任意的故障切换发生,都会伴随着选举的出现,以此来决定哪个成员成为primary。
     选举提供了一种机制,用于副本集中的成员无需管理员的干预,自动的选出一个新的primary。选举可以让副本集快速和坚决的从故障中恢复。当primary变为不可达时,secondary成员发起选举,第一个收到大多数选票的成员成为新的primary。
     前提:每个成员自能要求自己被选举成为主节点,只能为申请成为主节点的候选人投票
     当一个备份节点无法与主节点联通时 她就行联系并请求其他成员将自己选举为主节点,其他成员做几项理性的检查
  1. 自身是否能够与主节点联通
  2. 希望被选举为主节点的备份节点的数据是否是最新
  3. 有没有其他更高优先级的成员可以被选举为主节点
     当一个成员无法到达主节点时,他就会申请被选举为主节点,希望成为主节点的成员会他能到达的所有成员发出通知,告诉他们我要发起一轮选举,然后其他成员开始检查你是否具备成为候选人的资格,依据就是上面那三条,如果一条不符,直接取消选举,注意:只要有一人发现候选人不具备资格 选举就被否决了,比如说:可能发起选举分成员 就他自己本身不能连接到主节点.
假如 没有反对的理由:那么选举就开始了,其他成员就开始对这个成员投票 如果他得到副本集中大多数赞成票 他就会选举成功 他就会转换到主节点状态 如果达不到大多数赞成 他就失败了 依然是备份节点,之后还可以继续发起选举 主节点会一直处于主节点状态 出非他由于不在满足大多数的要求或者挂了退位,另外副本集被重新配置的时候也会导致主节点退位.
只要能够得到大多数成员的投票 他就会成为主节点
希望成为主节点的成员候选人 必须使用复制将自己的数据更新为最新.副本集中的其他成员会对此进行检查 复制操作是严格按照时间排序的 所有候选人的最后一条操作要比他能两天的其他成员更晚或者与其他成员相等
假设候选人执行的最后一个复制操作是123 他能联通的其他成员中有一个的最后复制操作是124 那么这个成员就会否决候选人的选举,这时候候选人会继续进行数据同步 等他同步到124时 他会重新请求选举(如果那时整个副本集中依然没有主节点的话)
成员优先级([praɪˈɔrɪti, -ˈɑr-)
在副本集中,每个成员都有优先级,它可以帮助决定选举出primary。默认情况下,所有的成员的优先级都为1。设置优先级:rs.add({"_id":4,"host":"iP:27017","priority":1.5});
选举仲裁者(arbiter)[ˈɑrbɪtɚ]
     他的唯一作用就是参与选举,他不会保存数据,也不会为客户端提供服务.他只是为帮助副本集能够满足大多数条件 所以可以选择比较垃圾的服务器来担当.启动方式和启动普通的mongod相同 使用--replset 副本集名称 和空的数据目录,可以使用rs.addArb()辅助函数将仲裁者添加到副本集中 ts.addArb("server-6:27017"); 或者在成员配置中指定arbiterOnly选项 rs.add({"_id":4,"host":"iP:27017","arbiterOnly":true}); 仲裁者和其他成员之间是不能相互转换的.
隐藏成员
     客户端不会想隐藏成员发送请求,因此 许多人会将不够强大的服务器或者备份服务器隐藏起来  
var config = rs.config();
config.members[2].hidden = 0;
config.members[2].priority = 0;
rs.reconfig(config);
这样就会将副本集中的成员隐藏起来了, 用isMaster命令 是看不见隐藏成员的,
延迟备份成员([dɪˈle])
     数据可能会因为人为错误而遭受毁灭性破坏,可能是不小心删除了组数据库或者出现了一个严重的bug把所有数据变成了垃圾,为了防止这类问题 可以使用slaveDelay设置一个延迟备份节点, 他的数据会比主节点延迟指定的时间,这是有意为之的,
     slaveDelay要求成员的优先级是0,如果你的应用程序会将请求路由到备份节点,应该将它隐藏掉,
 
二、副本集架构和部署模式
 
架构
副本集部署的架构对其容量和性能都有很大影响。大多数产品部署成包含3个优先级为1 的成员就足够了。
当开发一个副本集架构时要注意下面的因素:
  • 确保副本集的成员总能选出一个primary。运行奇数个成员或者运行一个仲裁者(arbiter)+偶数个成员。
  • 分布在不同地理位置的成员,知道“群体”的成员在任意网络分区中的情况。试图确保在主数据中心的成员中选举出primary。
  • 考虑副本集中包含hidden或者delayed成员用于支持专用功能,如备份、reporting和测试。
  • 考虑保留一或者两个位于其他数据中心的成员,同时通过配置确保其不会成为primary。
  • 使用replica set tags[tægz]创建定制的写规则以确保应用能够控制写操作成功的门限值。使用写规则确保操作在返回成功之前将操作传递给指定的数据中心或不同功能的机器。
部署策略
 
不存在一个理想的副本集架构可以满足任意部署环境。
最小的副本集推荐架构为三成员集合,其中一个为primary,另外两个为secondary,secondary在一定情况下可以成为primary。
如果副本集中的成员多于三个,则需要遵照下面的架构条件:
  • 集合中有奇数个参与投票的成员。如果有偶数个投票成员,则部署一个仲裁者将个数变为奇数。
  • 集合中同一时刻不多于7个参与投票的成员
  • 如果不想让某些成员在故障切换时成为primary,则将它们的优先级设为0。
  • 集合的多数成员运行在主要的数据中心
地理上的分布式集
 
一个基于地理的分布式副本集可以应对一个数据中心恢复失败的情况。这种集合至少包含了一个在备份数据中心的集合成员。
 
 
 
图:基于地理上的分布式副本集
如果primary掉线,则副本集选出一个新的primary;如果主数据中心和备数据中心连接失败,备数据中心的secondary不能成为primary。如果主数据中心失败,则需要人为的从备数据中心恢复数据。
值得注意的是,这种架构下,必须注意在主数据中心要保持奇数个参与投票的成员,上图中则需要在主数据中心添加一个仲裁者。
心跳
每个成员都需要知道其他成员的状态:哪个是主节点,哪个可以作为同步源 哪个挂掉了,为了维护最新视图.每个成员每个两秒就会向其他成员发送一条心跳请求 心跳请求信息量很小 用于检查每个成员的状态
 
心跳的最重要的功能之一 就是让主节点知道自己是否满足集合大多数的条件 如果主节点不再得到大多数服务器的支撑 他就会退位 变成备份节点.
 同步
     复制用于多台服务器hi见备份数据,mongodb的复制功能是使用操作日志oplog实现的,操作日志包含了主节点的每一次写操作,oplog是主节点的local数据库中的一个固定集合,备份节点通过查询这个集合就可以知道需要进行复制的操作
     每个备份节点都维护这自己的oplog,记录了每一次从主节点复制数据的操作,这样每个成员都可以作为同步源提供给其他成员使用.
处理陈旧数据
     如果备份节点远远落后与同步源当前操作,那么备份节点就会就是陈旧数据,陈旧的备份节点无法跟上同步源的节奏,因为同步源上的操作领先太多太多;如果继续同步,备份节点需要跳过一些操作,如果备份节点曾经停机过,发现写入量超过了自身处理能力,或者太多的读请求,这些情况都可能导致备份节点陈旧
     当一个备份节点陈旧之后,他会查看副本集中的其他成员,如果某个成员的oplog足够详细,可以用于处理那些落下的操作,就从这个成员处进行同步,如果任何一个成员的oplog都没有参考价值,那么这个成员上的复制操作就会中止,这个成员需要重新进行完全同步,
     为了避免陈旧被备份节点的出现,让主节点使用比较大的oplog保存足够多的操作日志很重要, 当然需要大的磁盘空间,通常来说这是一个比较好的折衷选择,因为磁盘会越来越便宜.
posted @ 2016-11-17 10:18  Darcy_wang  阅读(1606)  评论(0编辑  收藏  举报