导读:
在之前的文章中(超链接),我们说了MongoDB现在已经不再推荐使用主从复制模式,而是推荐副本集,那么副本集究竟有什么优点呢?我们不妨来探索一下。
(一)副本集(replica set)概述
对于副本集,官方文档是这样定义的:副本集是一组mongod维护相同数据的实例,一个副本集包含多个数据承载节点和一个仲裁节点(可选),在数据承载节点中,只有一个成员节点被视为主节点,主节点能够进行读写操作,其它节点则被视为次要节点,次要节点只能进行读操作。
(二)副本集的架构
(1)PSS架构
“一主两从”架构,如果主节点不可用,则符合条件的次要节点将进行选举以自行选举新的主要节点。
跨2个或多个数据中心分布的副本集:
在两个数据中心之间分布副本集成员可提供优于单个数据中心的好处。在两个数据中心分布中,
--如果其中一个数据中心发生故障,则与单个数据中心分发不同,该数据仍可读取。
--如果具有少数成员的数据中心发生故障,则副本集仍然可以同时执行写操作和读操作。
--但是,如果拥有大多数成员的数据中心发生故障,则副本集将变为只读。
如果可能,请在至少三个数据中心中分配成员。对于配置服务器副本集(CSRS),最佳实践是分布在三个(或更多,取决于成员的数量)中心中。如果第三个数据中心的成本过高,则一种分配可能性是,在公司政策允许的情况下,在两个数据中心之间平均分配数据承载成员,并将剩余成员存储在云中。
(2)PSA架构
在某些情况下(例如只有一个主服务器和一个辅助服务器,但由于成本限制,禁止添加另外一个服务器),你可以选择一个mongod实例作为仲裁器添加到副本集,仲裁节点参加选举,但是不保存数据。
(三)自动故障转移
当主节点与其它成员的通信时间超过参数electionTimeoutMillis(默认10000,即10s)的限定时,会发生自动故障转移,原来的某个从节点会转换角色为主节点。
(四)读取首选项(读写分离)
默认情况下,客户端从主节点读取数据,但是,客户端也可以指定首选项,将读取请求发送到从节点。
(五)MongoDB副本集成员
MongoDB副本集主要有三种成员:
- Primary:主节点
- Secondaries:从节点
- Arbiter:仲裁节点,可选。
(1)主节点
主节点是副本集中接收写操作的唯一成员,MongoDB在主数据库上执行写操作,然后再主数据库的oplog上记录操作,从节点复制该日志,将操作应用于从数据库。
在以下3节点副本集中,主数据库不可用,将会触发一次选举,将从节点之一选举为新的主节点。
(2)从节点(副本节点)
副本节点为只读节点,对于副本节点,可以将其配置为:
- 优先级为0的副本节点(Priority 0 Replica Set Members):不能够成为主节点和不能够触发选举,驻留在辅助数据中心或充当冷备用库。
- 隐藏副本节点(Hidden Replica Set Members):客户端应用程序不可见,阻止应用从节点读取数据,隐藏成员必须是优先级为0的成员
- 延迟副本节点(Delayed Replica Set Members):延迟应用日志,用于从某些错误(如误删数据)中恢复。延迟副本集成员必须是优先级为0 的成员,将优先级设置为0,以防止其成为主要成员;最好设置为隐藏成员,防止应用程序查看延迟数据。
(3)仲裁节点
在某些情况下(例如您有一个主服务器和一个辅助服务器,但由于成本限制,禁止添加另一个辅助服务器),您可以选择将仲裁器添加到副本集。一个仲裁器不具有数据集的副本,并不能成为主节点。但是,仲裁节点参加选举。仲裁员具有确切的1个投票。
(六)操作日志oplog
MongoDB在主数据库上执行写操作,并在操作日志中记录该操作,然后从数据库将日志异步同步过去并应用,每个副本集节点都包含一个oplog,保存在local.oplog.rs中。
因为每个副本集成员都存在oplog日志,为了促进复制,所有副本集成员都会发送心跳(pings)给所有的其它成员,任何从节点都可以从其它节点导入操作日志条目。
(1)oplog大小设置
首次启动副本集成员时,如果未指定操作日志大小,则MongoDB将创建默认大小的操作日志
默认操作日志大小取决于存储引擎:
储存引擎 默认操作日志大小 下界 上界 ----------------- ----------------- ------ ------- 内存中存储引擎 物理内存的5% 50兆字节 50 GB WiredTiger存储引擎 可用磁盘空间的5% 990兆字节 50 GB
在mongod创建操作日志之前,可以使用oplogSizeMB参数指定其大小,首次启动副本集成员之后,使用replSetResizeOplog命令更改操作日志大小。
(2)查看oplog状态
要查看操作日志状态,包括操作的大小和时间范围,可以使用rs.printReplicationInfo()方法。
【完】