MongoDB集群持续出现“No keys found for HMAC that is valid for time”错误的排查与解决求助
我之前碰到过一模一样的问题!从你贴的日志来看,这是MongoDB集群内部通信时的HMAC密钥验证失败,错误码211明确指向找不到对应时间戳的有效密钥,导致监控线程无法正常获取服务器描述信息。
先把你的错误日志整理出来方便参考:
----------- org.mongodb.driver.cluster:监控线程成功连接至服务器,服务器描述为ServerDescription{address=############-2.service.consul:37752, type=REPLICA_SET_OTHER, state=CONNECTED, ok=true, minWireVersion=0, maxWireVersion=7, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=30, roundTripTimeNanos=2831751, setName='rs_############', canonicalAddress=############-2.service.consul:37752, hosts=[############-2.service.consul:37752, ############-1.service.consul:37752, ############-0.service.consul:37752], passives=[], arbiters=[], primary='############-0.service.consul:37752', tagSet=TagSet{[]}, electionId=null, setVersion=1, topologyVersion=null, lastWriteDate=Thu May 20 22:55:57 UTC 2021, lastUpdateTimeNanos=2531300430939248} ----------- [ce.consul:37752] org.mongodb.driver.connection:已打开至############-2.service.consul:37752的连接[connectionId{localValue:65, serverValue:11656453}] ----------- [ce.consul:37752] org.mongodb.driver.cluster:连接至服务器############-2.service.consul:37752时,监控线程中出现异常 ----------- OUT com.mongodb.MongoCommandException:命令执行失败,错误码211(KeyNotFound):'Cache Reader No keys found for HMAC that is valid for time: { ts: Timestamp(1631194588, 3) } with id: 69#######4408579',发生在服务器b33a360#####8-bdd7-9214d51dc498-2.service.consul:37752上。完整响应为{"ok": 0.0, "errmsg": "Cache Reader No keys found for HMAC that is valid for time: { ts: Timestamp(1631194588, 3) } with id: 69841######08579", "code": 211, "codeName": "KeyNotFound"} ----------- OUT at com.mongodb.internal.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:175) ~[mongodb-driver-core-4.1.2.jar:na] ----------- OUT at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:359) ~[mongodb-driver-core-4.1.2.jar:na] ----------- OUT at com.mongodb.internal.connection.InternalStreamConnection.receive(InternalStreamConnection.java:305) ~[mongodb-driver-core-4.1.2.jar:na] ----------- at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.lookupServerDescription(DefaultServerMonitor.java:218) ~[mongodb-driver-core-4.1.2.jar:na] ----------- OUT at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:144) ~[mongodb-driver-core-4.1.2.jar:na] ----------- OUT at java.base/java.lang.Thread.run(Unknown Source) ~[na:na]
问题原因分析
这个错误本质是:MongoDB集群节点之间用HMAC签名来验证内部通信的合法性,当某个节点的密钥缓存里,找不到对应请求时间戳的有效密钥时,就会抛出这个错误。常见诱因包括:
- 集群节点的密钥文件不一致(如果用keyFile认证)
- 节点的密钥缓存没有及时更新(比如自动密钥轮换后同步延迟)
- 集群节点之间系统时间不同步(时间差导致密钥有效时间判断错误)
具体解决步骤
第一步:检查并统一集群密钥配置
如果你的集群用的是keyFile认证模式,登录到每个节点,确保keyFile的内容完全一致,并且文件权限设置为600(只有所有者可读可写)。可以用md5sum命令验证文件哈希值是否相同:md5sum /path/to/your/mongodb-keyfile如果是用KMIP或者自动密钥轮换,跳过这一步,直接看下一步。
第二步:刷新节点的密钥缓存
登录到报错的MongoDB节点,执行以下命令强制刷新集群认证缓存:db.adminCommand({invalidateClusterCache: "auth"})注意:如果是副本集,先从secondary节点开始操作,最后再操作primary,避免影响业务。执行后观察日志,看看错误是否消失。
第三步:检查密钥集合的一致性
在每个节点上查询system.keys集合,确认所有节点的有效密钥条目一致,且覆盖报错的时间戳:db.system.keys.find({ expiresAt: { $gt: new Date(1631194588 * 1000) } })对比各个节点的结果,如果某个节点缺少对应密钥,手动同步或者触发密钥重新分发。
第四步:检查节点时间同步
集群节点的时间必须严格同步!用以下命令检查每个节点的时间:# 检查系统时间 timedatectl # 检查NTP同步状态 ntpq -p如果时间差超过几秒,立刻修复NTP配置,确保所有节点时间同步。时间不同步会导致密钥的有效时间判断出错,是这类问题的常见隐蔽原因。
如果以上步骤都做完还是有问题,可以尝试重启报错的节点(先secondary后primary),一般就能解决缓存不一致的问题。
内容的提问来源于stack exchange,提问作者eyeeaaaa

