MongoDB作为如今主流的文档型数据库,在大小公司都有广泛的应用。相信对服务有可用性要求的公司,都或多或少会用到复制集功能。复制集正是MongoDB提供的一整套高可用性的解决方案。现阶段很多文章都是
MongoDB作为如今主流的文档型数据库,在大小公司都有广泛的应用。相信对服务有可用性要求的公司,都或多或少会用到复制集功能。复制集正是MongoDB提供的一整套高可用性的解决方案。现阶段很多文章都是讲述如何创建一个副本集,但是对副本集的原理很少提示。所以,第一篇文章将详尽的阐述其中各个概念,以便你对复制集功能有个整体的了解。
复制集是什么?
现在假设你运行一个web服务,服务后面连着一个MongoDB实例。如果这个时候实例挂掉了,整个web服务都将不可用,这在生产环境一定是不允许的。那么如果我们运行多个MongoDB的实例,挂掉一个由另外一个顶上,整个服务的可用性都将大幅提高。这样的多个实例的集合就称为复制集。当然复制集上的实例,都保存着相同的数据。
基本架构
MongoDB实现的复制集是主从架构,如下图所示
在复制集中存在两种不同类型的节点分别是Primary
(后文用主节点指代)以及Secondary
(后文用从节点指代)。
在一个复制集中只能存在一个主节点,但可以存在多个从节点。从节点不可接受写入操作,主节点接受写入操作,通过oplog
的形式,将数据同步给从节点。oplog
是数据的写入的日志。你插入一条记录,那么日志就会增加一行插入操作。从节点拿到日志,在自己服务上面重放这个操作,就实现了数据的同步。
选举
当我们的主节点因为意外情况挂掉,其他从节点会选举出一个节点作为新的主节点。
Raft
(zh.wikipedia.org/wiki/Raft)。一般来说选举会发生在以下几种情况里面:
- 复制集添加新节点
- 初始化一个复制集
- 修改了整个集群的配置
- 从节点和主节点失去连接时间过长(通常默认10s)
Write Concern
当我们只有一台MongoDB实例的时候,客户端的一个插入记录,写入成功直接返回success。但是,现在我们有一个复制集,那么客户端的写入操作怎么才算成功写入呢?
这就要提到MongoDB的写入配置Write Concern
。Write Concern
是这样一种k,v结构{ w: <value>, j: <boolean>, wtimeout: <number> }
。
- w:
w表示需要多少个节点确认才算写入成功,默认值为1({'w': 1}
)。表示写入Primary
节点后就算写入成功。如果填n
表示需要写入n个节点,才能够算写入成功。
w还有另一种选项majority
,表示写入大部分节点算成功写入。举个例子,现在有3个节点参与选举投票,那么成功写入2个就算写入成功。
- j:
j表示是否需要成功写入journal files
。
- wtimeout:
表示超时时间,这里需要额外注意,在有的临界点写入成功也有可能返回超时。但是MongoDB是不会去回滚写入成功的数据的。
Write Concern
可以直接修改集群配置
cfg = rs.conf()cfg.settings.getLastErrorDefaults = { w: "majority", wtimeout: 5000 }rs.reconfig(cfg)
也可以增加
db.products.insert( { item: "envelopes", qty : 100, type: "Clasp" }, { writeConcern: { w: "majority" , wtimeout: 5000 } })
第二个参数做单独的配置。
五类从节点
MongoDB的从节点可以大致分为五类:
- 普通从节点
这类从节点属于priority
为1,可以正常的选举,复制数据。
- Priority为0的节点
这类节点只能复制数据,不能被选举为主节点,也不能触发选举的开始。这类节点通常作为跟随节点。所谓跟随节点,只存储数据,当普通节点宕机时,可以迅速替换到主节点。
- 隐藏节点
隐藏节点对于客户端是不可见的,隐藏节点的priority一定要为0.
- 延迟节点
延迟节点不会立即同步主节点的数据,会有个时间上的延迟。比方说7点主节点写入一条数据,8点延迟节点才会同步这点数据。延迟节点最好设置为隐藏节点,以免客户端读取到脏数据。延迟节点的作用,主要是作为备份和回滚使用。
- 仲裁者节点(Arbiter)
这类节点不含数据,仅仅是作为投票使用。有的时候我们可能有4个节点用来投票,但是投票节点数需要奇数个,就可以部署一台仲裁者,使投票节点数为奇数。
从节点数据同步
和redis
相似,数据同步遵循两种形式,当新节点加入集群时,为把数据全量传输过去。第一次同步过后,会根据oplog
进行操作重放,增量更新。

- 0