MongoDB 在今年正式发布了新的 4.4 大版本,这次的发布包含众多的增强 Feature,可以称之为是一个维护性的版本,而且是一个用户期待已久的维护性版本,MongoDB 官方也把这次发布称为「User-Driven Engineering」,说明新版本主要是针对用户呼声最高的一些痛点,重点进行了改进。
而阿里云作为 MongoDB 官方的全球战略合作伙伴,也即将全网独家上线 4.4 新版本,下面就由阿里云 MongoDB 团队的工程师针对一些用户关注度比较高的 Feature ,进行深度解读。
可用性和容错性增强
Mirrored Reads
在服务阿里云 MongoDB 客户的过程中,笔者观察到有很多的客户虽然购买的是三节点的副本集,但是实际在使用过程中读写都是在 Primary 节点,其中一个可见的 Secondary 并未承载任何的读流量。
那么在偶尔的宕机切换之后,客户能明显的感受到业务的访问延迟会有抖动,经过一段时间后才会恢复到之前的水平,抖动原因就在于,新选举出的主库之前从未提供过读服务,并不了解业务的访问特征,没有针对性的对数据做缓存,所以在突然提供服务后,读操作会出现大量的「Cache Miss」,需要从磁盘重新加载数据,造成访问延迟上升。在大内存实例的情况下,这个问题更为明显。
在 4.4 中,MongoDB 针对上述问题实现了「Mirrored Reads」功能,即,主库会按一定的比例把读流量复制到备库上执行,来帮助备库预热缓存。这个执行是一个「Fire and Forgot」的行为,不会对主库的性能产生任何实质性的影响,但是备库负载会有一定程度的上升。
流量复制的比例是可动态配置的,通过 mirrorReads 参数设置,默认复制 1% 的流量。
此外,可以通过db.serverStatus( { mirroredReads: 1 } )来查看 Mirrored Reads 相关的统计信息,
Resumable Initial Sync
在 4.4 之前的版本中,如果备库在做全量同步,出现网络抖动而导致连接闪断,那么备库是需要重新开始全量同步的,导致之前的工作全部白费,这个情况在数据量比较大时,比如 TB 级别,更加让人崩溃。
而在 4.4 中,MongoDB 提供了,因网络异常导致全量同步中断情况下,从中断位置恢复全量同步的能力。在尝试恢复一段时间后,如果仍然不成功,那么会重新选择一个同步源进行新的全量同步。这个尝试的超时时间默认是 24 小时,可以通过 replication.initialSyncTransientErrorRetryPeriodSeconds 在进程启动时更改。
需要注意的是,对于全量同步过程中遇到的非网络异常导致的中断,仍然需要重新发起全量同步。
Time-Based Oplog Retention
我们知道,MongoDB 中的 Oplog 集合记录了所有的数据变更操作,除了用于复制,还可用于增量备份,数据迁移,数据订阅等场景,是 MongoDB 数据生态的重要基础设施。
Oplog 是作为 Capped Collection 来实现的,虽然从 3.6 开始,MongoDB 支持通过 replSetResizeOplog 命令动态修改 Oplog 集合的大小,但是大小往往并不能准确反映下游对 Oplog 增量数据的需求,考虑如下场景,
• 计划在凌晨的 2 - 4 点对某个 Secondary 节点进行停机维护,应避免上游 Oplog 被清理而触发全量同步。
• 下游的数据订阅组件可能会因为一些异常情况而停止服务,但是最慢会在 3 个小时之内恢复服务并继续进行增量拉取,也应当避免上游的增量缺失。
所以,在真实的应用场景下,很多时候是需要保留最近一个时间段内的 Oplog,这个时间段内产生多少的 Oplog 往往是很难确定的。
在 4.4 中,MongoDB 支持 storage.oplogMinRetentionHours 参数定义最少保留的 Oplog 时长,也可以通过 replSetResizeOplog 命令在线修改这个值,如下,<