uncategorized

Replication In MongoDB

MongoDB

冗余和数据可用性

  • 副本集提供了数据冗余,增强了数据的可用性。
  • 在多个服务器上部署副本集可提供对单点故障的容错能力。
  • 副本集可以提高读能力——分发请求到多个服务器。

MongoDB中的副本集

  • 一个副本集由多个mongod实例组成,它们管理着同一组数据。
  • 一个副本集包含多个数据节点和一个可选的仲裁节点;数据节点中有且仅有一个主节点,其它的节点为副节点。
  • 所有写操作由主节点处理。
  • 主节点在日志中记录所有的改变,副本节点通过日志复现主节点的改变。
  • 主节点不可用时,符合条件的副节点发起选举尝试选举自己为主节点。
  • 仲裁节点作为一个有投票权的节点,不存储数据。

异步复制

  • 副本节点通过日志来重复主节点的修改,从而达到数据同步的目的

自动故障转移

  • 当主节点和其他节点不通信的时间超过指定时间(electionTimeoutMillis配置,默认10s),符合条件的副节点会提名自己成为主节点,集群会尝试选出新的主节点。
  • 选举过程中副本集不能处理写操作,但可以处理在副节点上的读操作。

读操作

  • 副本集默认的读写节点为主节点,通过设置read-preference来读取副节点。
  • 由于异步复制的机制,从副节点读取的数据不是实时的数据。
  • 多文档事务中必须指定read-preference为主节点。
  • 事务中的所有操作必须由同一节点处理。

副本集成员

  • 一个副本集推荐3个数据节点,或者两个数据节点+一个仲裁节点。
  • 副本集最多50个节点,最多7个能投票的节点。

主节点

  • 主节点处理所有写操作,并记录操作日志

副节点

  • 副节点通过操作日志重复主节点的操作,从而达到管理同一个数据集的目的
  • 零优先级(priority)的副节点不能成为主节点,也不能触发选举过程,但是可以存储数据、处理读操作、投票
  • 隐藏(hidden)的副节点是零优先级的,且不处理读操作,只是单纯的复制数据,可以投票
  • 隐藏节点可用来作为数据备份
  • 延迟(delayed)的副节点是零优先级的、应该是隐藏的,数据相对当前数据集有一定延迟时间
  • 延迟的副节点可用来恢复误操作导致的数据库被删除

仲裁节点

  • 仲裁节点不存储数据,不能当主节点,只有投票权
  • 仲裁节点和其它节点的交流信息只包含:投票, 心跳, 配置数据

副本集操作日志

  • 操作日志是一个固定大小的collection,记录了所有修改数据的操作。
  • 副本集基于操作日志实现。
  • 主节点记录操作日志,副节点复制日志并重复操作。
  • 为了加快复制操作,所有节点可以发送心跳到其它节点,任何副节点都可以从其它节点复制操作日志。
  • 操作日志中的每条记录是幂等的。

操作日志大小

  • 默认5%的剩余磁盘空间大小(990M~50G)
  • 创建mongod时指定oplogSizeMB设定操作日志大小。
  • 使用replSetResizeOplog命令动态设置日志大小。
  • 少量的写操作和大量的读操作的情况下,较小的操作日志会更加有效率。

副本集数据同步

初始化同步

  • 初始化同步即复制整个数据集(除local)到目标节点。
  • 初始化同步有内置的重试逻辑来提高容错性。

复制

  • 从源节点复制操作日志到目标节点,再按日志重现操作。
  • 源节点会根据ping time和副本状态切换。
  • 避免从隐藏节点、延迟节点复制。

多线程复制

  • MongoDB使用多线程和批处理来提高并发:按照文档的_id字段分组,即每组只操作一个文档,每组使用不同的线程操作。
  • 使用批处理时,MongoDB阻塞所有的读操作,以免读取到中间状态。

副本集的高可用性

副本集选举

  • 副本集通过选举来决定那一个成员成为主节点
  • 以下情形发生时触发选举:
    • 新的节点被添加到副本集
    • 初始化副本集
    • 使用rs.stepDown(), rs.reconfig()
    • 副本节点和主节点失去连接超过指定时间
  • 选举期间副本集不能处理写操作
  • 节点每两秒向其它成员发送心跳信息,如果一个节点10秒内不回复,其它节点标记它为不可访问
  • 选出主节点后,如果存在优先级最高的可用节点不是主节点,则再次选举直到它成为主节点
  • 由于网络分割导致主节点只能连接少数节点时,主节点自动降级为副节点;能连接大部分节点的尝试选举新的主节点。

故障转移中的回滚

  • 前一个主节点从故障中恢复,以副节点的身份重新加入副本集时:如果该节点存在已接受的写操作,但是其它的节点没有完成该操作时,该节点需要回滚写操作来保持数据的一致性。
  • 如果发生了回滚,在dbPath目录下的rollback目录下,以<database>.<collection>.<timestamp>.bson格式存放回滚数据(使用bsondump工具转换bson数据)。
  • 为了防止回滚,设置writeConcern:majority并启动日志:保证在大多数节点接受写请求后才给客户端确认信息。
  • 回滚之前,等待正在后台建立索引的过程完成(4.0)。
  • 回滚数据量无大小限制(4.0)。
  • 回滚时间限制默认为24小时内(4.0)。
Share