复制延迟使“滞后”成员没有资格快速成为主节点 (primary node in the replica set),并增加分布式读取操作不一致的可能性。
本页包含一些可以减少复制延迟的提示,但许多情况下可能需要升级。如果无法确定复制延迟的原因或需要其他支持,联系技术支持。
先决条件检查
要检查部署的当前复制延迟长度,请执行以下操作:
在连接到主节点 (primary node in the replica set)的
mongosh会话中,调用rs.printSecondaryReplicationInfo()方法以显示每个从节点(secondary node from replica set)上相对于主节点 (primary node in the replica set)托管的当前延迟。返回每个成员的
syncedTo值,该值显示最后一个 oplog 条目写入辅助节点的时间,如以下示例所示:source: m1.example.net:27017 syncedTo: Thu Apr 10 2014 10:27:47 GMT-0400 (EDT) 7230 secs (2 hrs) behind the primary source: m2.example.net:27017 syncedTo: Thu Apr 10 2014 10:27:47 GMT-0400 (EDT) 0 secs (0 hrs) behind the primary 落后主节点 (primary node in the replica set)的秒数可以告诉您从从节点(secondary node from replica set)落后主节点 (primary node in the replica set)的程度。
当主节点上的不活动时段大于
members[n].secondaryDelaySecs值可能会显示为落后于主节点0秒。在Atlas部署中,通过检查Cloud Manager和Ops Manager提供的 Replication Lag图表中的非零或递增的oplog时间值监控Atlas部署中的复制速率。
此外,您可以通过检查集群指标标签页中的 Replication Lag、Oplog GB/Hour 和 Replication Oplog Window监控Atlas中的复制延迟。有关更多信息,请参阅查看可用指标。
常见问题和解决方案
复制延迟没有错误代码,也没有立即确定原因的方法。但是,在升级到支持之前,请检查以下问题是否可能导致延迟:
网络延迟
当集群节点彼此无法可靠通信时,可能会构建复制延迟。
检查副本集节点之间的网络路由,确保不存在数据包丢失或网络路由问题。
使用包括 ping 在内的工具来测试设立节点之间的延迟,并使用 traceroute 来公开网络端点之间数据包的路由。
或者,运行replSetGetStatus 并检查 pingMs字段。这将返回主节点 (primary node in the replica set)和从节点(secondary node from replica set)节点之间的当前网络延迟(以毫秒为单位)。
从节点资源耗尽
当从节点(secondary node from replica set)无法有效处理来自主节点 (primary node in the replica set)的传入读取操作时,可能会出现资源争用。这可能会导致缓存争用等内存问题。当缓存达到关键阈值时,服务器会使用应用程序线程逐出页面,从而减少可用于管理复制的线程数。
要查看服务器是否将应用程序线程重定向到逐出任务,请在 mongosh Shell中运行以下命令:
db.serverStatus().wiredTiger.cache['pages evicted by application threads']
如果结果 = 0:没有应用程序程序线程因驱逐而暂停。
如果结果 > 0(且不断增加):数据库面临缓存压力。传入查询必须在执行之前逐出缓存的数据,这可能会增加复制延迟。
Atlas用户还可以监控WiredTiger Cache Activity 和 Page Faults指标,以调查缓存相关问题。
有关解决此问题的潜在策略,请参阅扩展资源。
磁盘相关问题
如果节点从节点(secondary node from replica set)无法足够快地将脏数据刷新到磁盘,它就会落后于主节点 (primary node in the replica set)。当来自主节点 (primary node in the replica set)的写入量超过从节点(secondary node from replica set)磁盘的写入速度时,就会出现这种现象。
与磁盘相关的问题在多租户系统(包括虚拟化实例)中普遍存在,如果系统通过IP网络访问磁盘设备,这些问题可能是暂时性的。
要评估磁盘状态,请使用系统级工具,例如 iostat 或 vmstat。
Atlas用户可以访问Atlas指标如Disk IOPS 和 Disk Space Used 来调查磁盘问题。
磁盘问题的一些常见原因包括:
预配不足:从从节点(secondary node from replica set)的磁盘速度比主节点 (primary node in the replica set)慢,或 IOPS 低。
虚拟化开销:在共享环境中,其他虚拟机可能会使物理磁盘控制器饱和。
磁盘问题的一些可能的解决方案包括:
增加预配IOPS
升级到 NVMe 存储
升级到更高的Atlas 集群层。有关更多信息,请参阅Atlas集群大小调整和层级选择。
长时间运行的操作
在某些情况下,主节点上长时间运行的操作可能会阻止从节点上的复制。为获得最佳结果,请将写关注配置为需要确认复制到从节点。这样可以防止在复制跟不上写入负载时返回写入操作。
您还可以使用数据库分析器来识别与观察到的延迟相关的慢速查询或长时间运行的操作。
写入负载过多
批量写入操作可能会超出副本集的及时复制能力,从而导致复制延迟。
以下小节提供了此问题的可能解决方案:
使用较小的批次
通过批处理和筛选增删改查命令来控制负载。
针对日期或时间范围(例如月、周或日)运行每个批处理。确保查询筛选条件使用索引以避免集合扫描。集合扫描可能会从工作集逐出数据和索引页,并增加复制延迟。
首先删除小日期范围。如果这些操作在几秒钟内完成,请增加批处理大小。使用 rs.printSecondaryReplicationInfo() 监控复制延迟。增加批处理大小,直到在吞吐量和复制延迟之间达到平衡。继续监控系统负载、对其他用户和应用程序的影响以及从节点的延迟程度。
例如:
db.collName.deleteMany({createdDate: {$gte: new Date("2018-12-01"), $lt: new Date("2019-01-01")}}); db.collName.deleteMany({createdDate: {$gte: new Date("2018-11-01"), $lt: new Date("2018-12-01")}}); db.collName.deleteMany({createdDate: {$gte: new Date("2018-10-01"), $lt: new Date("2018-11-01")}});
配置服务器端设置和参数
MongoDB提供以下服务器端设置和参数,可在写入密集型操作期间控制资源使用情况:
storageEngineConcurrentWriteTransactions:降低此值可以减少当其他写入操作同时发生时批量删除引起的争用。注意
修改
storageEngineConcurrentWriteTransactions时要小心,因为更改设置可能会导致性能问题或错误。我们建议您在更改参数之前咨询MongoDB支持部门。maxTimeMS:如果批量写入操作比较复杂,可以限制其执行时间,防止长时间运行影响服务器性能。复杂操作的一些示例包括匹配许多文档或按非索引字段进行查询。
按索引顺序删除文档
如果您运行批量操作的字段未建立索引,则批量操作可能会导致集合或表扫描,从而增加资源使用量。确保查询筛选条件中使用的字段存在索引,以加快删除速度,减少锁争用并提高性能。
在运行操作之前创建索引:
db.collection.createIndex({ status: 1 });
然后根据索引字段删除:
db.collection.deleteMany({ status: "inactive" });
oplog window Size
如果oplog window对于要同步的数据量来说太小,则可能会遇到复制延迟。较大的oplog可以为副本集提供更大的延迟容忍度。
要检查给定副本集成员的oplog大小及其操作的日期范围,请连接到 mongosh 中的该节点并运行rs.printReplicationInfo() 方法。oplog应足够长,以容纳您对从从节点(secondary node from replica set)预期的最长停机时间内的所有事务。[1] oplog至少应能够保存至少 24 小时的操作;但是,许多用户更愿意有 72 小时甚至一周的工作时间。
注意
通常,您希望所有成员的 oplog 大小相同。如果您调整了 oplog 的大小,请对所有成员的 oplog 大小进行调整。
要更改 Oplog 大小,请参阅更改自管理副本集成员的 Oplog 大小教程。
| [1] | oplog 的大小可能会超过其配置的大小限制,从而避免删除 majority commit point。 |
验证分辨率
要确认问题已解决,请调用 rs.printSecondaryReplicationInfo() 方法并检查是否不再有任何滞后成员。
为获得更多支持而收集的诊断信息
如果上述解决方案都无法减少延迟,联系支持。支持人员可能会要求进行诊断,以进一步诊断问题。
Atlas用户可以收集一些有用的诊断信息以获取支持,这些诊断信息包括:
延迟开始的时间线
最近对部署进行的任何更改,例如对模式、索引、应用程序、层级或硬件的更改。