副本集故障排除
本节介绍对副本集部署进行故障排除的常用策略。
检查副本集状态
要显示副本集的当前状态和每个节点的当前状态,请在已连接到副本集主节点的 mongosh
会话中运行 rs.status()
方法。有关 rs.status()
所显示信息的说明,请参阅 replSetGetStatus。
注意
rs.status()
方法是运行 replSetGetStatus
数据库命令的包装器。
检查复制延迟
复制延迟是指主节点上的操作与将该操作从 oplog 应用到从节点之间的延迟。复制延迟可能是一个重要问题,可能会严重影响 MongoDB 副本集部署。过多的复制延迟使得“滞后”成员失去快速成为主节点的资格,并且增加了分布式读取操作不一致的可能性。
要查看当前的复制延迟时长,请执行以下操作:
在连接到主节点的
mongosh
会话中,调用rs.printSecondaryReplicationInfo()
方法。返回每个成员的
syncedTo
值,该值显示最后一个 oplog 条目写入辅助节点的时间,如以下示例所示:source: m1.example.net:27017 syncedTo: Thu Apr 10 2014 10:27:47 GMT-0400 (EDT) 0 secs (0 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 当主节点上的不活动时段大于
members[n].secondaryDelaySecs
值可能会显示为落后于主节点0
秒。注意
rs.status()
方法是replSetGetStatus
数据库命令的包装器。从 MongoDB 6.0.13开始 (和5.0.24 ),慢查询日志消息中的
totalOplogSlotDurationMicros
显示写入操作获取提交时间戳以提交存储引擎写入内容与实际提交之间的时间。mongod
支持并行写入。 但是,它可以按任意顺序提交带有提交时间戳的写操作。例子
考虑以下带有提交时间戳的写入:
writeA with Timestamp1
writeB with Timestamp2
writeC with Timestamp3
假设 WriteB 首先在 Timestamp2 提交。复制暂停到 writeA 提交,因为需要 writeA 的带 Timestamp1 的 oplog 条目才能将 oplog 复制到副本集从节点。
查看 Cloud Manager 和 Ops Manager 中提供的 Replication Lag 图表,通过其中的非零或增加的 oplog 时间值来监控复制速度。
复制延迟原因
复制延迟的可能原因包括:
网络延迟
检查您的集成员之间的网络路由,确保没有数据包丢失或网络路由问题。
使用包括
ping
在内的工具来测试集成员之间的延迟,并使用traceroute
来公开数据包网络端点的路由。磁盘吞吐量
如果从节点上的文件系统和磁盘设备无法像主节点一样快地将数据刷新到磁盘,则从节点将难以保持状态。与磁盘相关的问题在多租户系统(包括虚拟化实例)上非常普遍,另外,如果系统通过 IP 网络访问磁盘设备(如 Amazon 的 EBS 系统中的情况),则问题可能是暂时的。
使用系统级工具评估磁盘状态,包括
iostat
或vmstat
。并发
在某些情况下,主节点上长时间运行的操作可能会阻止从节点上的复制。为获得最佳结果,请将写关注配置为需要确认复制到从节点。这样可以防止在复制跟不上写入负载时返回写入操作。
您还可以使用数据库分析器查看是否存在与延迟事件相对应的查询缓慢情况或长时间运行的操作。
适当的写关注
如果您正在执行大型数据摄取或批量加载操作,需要对主节点进行大量写入操作,尤其是使用
unacknowledged write concern
执行写入操作,则从节点读取 oplog 的速度将不够快,无法跟上变化。为避免这种情况,可在每 100、1,000 或其他间隔后请求写确认写关注,以便为从节点成员提供追赶主节点的机会。
有关更多信息,请参阅:
流量控制
从 MongoDB 4.2 开始,管理员可以限制主节点应用写入的速率,目标是将 majority
committed
延迟保持在可配置的最大 flowControlTargetLagSeconds
值以下。
默认情况下,流量控制为 enabled
。
注意
为了进行流量控制,副本集/分片分片集群必须具有:featureCompatibilityVersion (FCV) 和读关注(read concern) 4.2
majority enabled
。也就是说,如果FCV不是4.2
或已禁用读关注(read concern)多数,则启用的流量控制不起作用。
启用流量控制后,随着延迟接近 flowControlTargetLagSeconds
,主节点上的写入操作必须先获取票据,然后才能获取锁以应用写入操作。通过限制每秒发出的票据数量,流量控制机制将尝试将延迟保持在目标延迟以下。
复制延迟可能发生在副本集没有接收到足够的负载来启用流量控制的情况,例如从节点无响应的情况。
要查看流量控制状态,请在主节点上运行以下命令:
运行
rs.printSecondaryReplicationInfo()
方法,确定是否有节点滞后:rs.printSecondaryReplicationInfo() 示例输出:
source: 192.0.2.2:27017 { syncedTo: 'Mon Jan 31 2022 18:58:50 GMT+0000 (Coordinated Universal Time)', replLag: '0 secs (0 hrs) behind the primary ' } --- source: 192.0.2.3:27017 { syncedTo: 'Mon Jan 31 2022 18:58:05 GMT+0000 (Coordinated Universal Time)', replLag: '45 secs (0 hrs) behind the primary ' } 运行
serverStatus
命令并使用flowControl.isLagged
值确定副本集是否已启用流量控制:db.runCommand( { serverStatus: 1 } ).flowControl.isLagged 示例输出:
false 如果流量控制尚未启用,请调查从节点以确定复制延迟的原因,例如硬件、网络或应用程序的限制。
有关流量控制统计的相关信息,请参阅:
Oplog 条目的应用缓慢
现在,副本集的从节点会记录应用时间超过慢操作阈值的 oplog 条目。这些慢 oplog 消息:
在
diagnostic log
中针对从节点记录。记录在
REPL
组件下,该组件将含有文本applied op: <oplog entry> took <num>ms
。不依赖日志级别(系统级别或组件级别)
不依赖于分析级别。
受
slowOpSampleRate
影响。
分析器不会捕获慢 oplog 条目。
测试所有成员之间的连接
副本集的所有成员必须能够连接到该集的每个其他成员,以支持复制。始终验证“双向”连接。网络拓扑和防火墙配置可能会阻止正常连接和必需的连接,从而阻止复制。
警告
在绑定到非本地主机(例如 可公开访问的) IP解决,确保已保护集群免遭未经授权的访问权限。 有关安全建议的完整列表,请参阅自托管部署的安全检查清单。 至少应考虑启用身份验证并强化网络基础架构。
MongoDB 二进制文件 mongod
和 mongos
默认绑定到本地主机。如果为此二进制文件设置了 net.ipv6
配置文件设置或 --ipv6
命令行选项,则该二进制文件还会绑定到本地主机 IPv6 地址。
默认情况下,绑定到本地主机的 mongod
和 mongos
只接受来自同一计算机上运行的客户端的连接。这种绑定行为包括 mongosh
和副本集或分片集群的其他节点。远程客户端无法连接到仅绑定到本地主机的二进制文件。
要覆盖默认绑定并绑定到其他 IP 地址,请使用 net.bindIp
配置文件设置或 --bind_ip
命令行选项来指定主机名或 IP 地址的列表。
警告
从 MongDB5.0 开始, 水平分割 DNS 仅配置了 IP 地址的节点无法启动验证并报告错误。请参阅disableSplitHorizonIPCheck
。
例如,以下 mongod
实例会绑定到本地主机和主机名 My-Example-Associated-Hostname
,而该主机名与 IP 地址 198.51.100.1
相关联:
mongod --bind_ip localhost,My-Example-Associated-Hostname
为了连接到此实例,远程客户端必须指定主机名或其关联的 IP 地址 198.51.100.1
:
mongosh --host My-Example-Associated-Hostname mongosh --host 198.51.100.1
考虑以下网络双向测试的示例:
例子
给定一个副本集,其中有三个成员在三个独立主机上运行:
m1.example.net
m2.example.net
m3.example.net
所有三个成员均使用默认端口 27017
。
使用以下操作集
m1.example.net
测试从m1.example.net
到其他主机的连接:mongosh --host m2.example.net --port 27017 mongosh --host m3.example.net --port 27017 使用来自
m2.example.net
的以下操作集测试从m2.example.net
到其他两个主机的连接,如下所示:mongosh --host m1.example.net --port 27017 mongosh --host m3.example.net --port 27017 您现在已经测试了
m2.example.net
和m1.example.net
之间的双向连接。使用来自
m3.example.net
主机的以下操作集测试从m3.example.net
到其他两个主机的连接,如下所示:mongosh --host m1.example.net --port 27017 mongosh --host m2.example.net --port 27017
如果任何方向的任何连接失败,请检查您的网络和防火墙配置并重新配置您的环境,以支持这些连接。
重新启动多个辅助节点时出现套接字异常
当您重新启动副本集的成员时,请确保该副本集能够在维护期间选出主节点。这意味着要确保该集中的大部分 members[n].votes
可用。
当某个集的大部分成员都不活跃时,该集的主节点会降级,成为从节点。主节点在降级时不会关闭客户端连接。
在成员选出新的主节点之前,客户端无法向副本集写入内容。
例子
给定一个由三名成员组成的副本集,其中每个成员都有一票,如果至少有两个成员可以相互连接,则该副本集可以选出一个主节点。如果您同时重新启动两个从节点,主节点将降级,成为从节点。在至少另一个从节点变为可用之前,即至少一个重新启动的从节点也变为可用之前,该副本集中没有主节点,并且无法选出新的主节点。
有关投票的更多信息,请参阅副本集选举。有关连接错误的相关信息,请参阅 TCP keepalive
时间会影响 MongoDB 部署吗?
检查 Oplog 的大小
较大的 oplog 可以为副本集提供更大的延迟容差,并使副本集更具弹性。
要检查给定副本集成员的 oplog 大小,请连接到 mongosh
中的成员并运行 rs.printReplicationInfo()
方法。
输出显示 oplog 的大小以及 oplog 中所包含操作的日期范围。在以下示例中,oplog 约为 10 MB,能够容纳大约 26 小时(94400 秒)的操作:
configured oplog size: 10.10546875MB log length start to end: 94400 (26.22hrs) oplog first event time: Mon Mar 19 2012 13:50:38 GMT-0400 (EDT) oplog last event time: Wed Oct 03 2012 14:59:10 GMT-0400 (EDT) now: Wed Oct 03 2012 15:00:21 GMT-0400 (EDT)
oplog 应该足够长,以容纳您对从节点预期的最长停机时间内的所有事务。[1] oplog 至少应能够保存至少 24 小时的操作;但是,许多用户更倾向于有 72 小时甚至一周的操作时间。
有关 oplog 大小如何影响操作的更多信息,请参阅:
注意
通常,您希望所有成员的 oplog 大小相同。如果您调整了 oplog 的大小,请对所有成员的 oplog 大小进行调整。
要更改 Oplog 大小,请参阅更改自管理副本集成员的 Oplog 大小教程。
[1] | oplog 的大小可能会超过其配置的大小限制,从而避免删除 majority commit point 。 |