Mongodb 4.2.8: 无法将会话添加到缓存中,因为活动会话数太高

Mongodb 4.2.8: Unable to add session into the cache because the number of active sessions is too high

在连接到 Mongo 期间,我们突然开始遇到以下问题:{u'code': 261, u'ok': 0.0, u'$clusterTime': {u'clusterTime': Timestamp(1614532995, 3141), u'signature': {u'keyId': 0L, u'hash': Binary('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 0)}}, u'codeName': u'TooManyLogicalSessions', u'operationTime': Timestamp(1614532995, 3141), u'errmsg': u'Unable to add session into the cache because the number of active sessions is too high'}

我们使用的任何连接驱动程序都会发生这种情况:

并不是每个查询都会发生,但大约占所有查询的 30-40%。

同时,maxSession 具有默认值 (1000000),我从数据库状态中获得以下数据:

"logicalSessionRecordCache" : {
        "activeSessionsCount" : 2244,
        "sessionsCollectionJobCount" : 48430,
        "lastSessionsCollectionJobDurationMillis" : 0,
        "lastSessionsCollectionJobTimestamp" : ISODate("2021-02-28T16:56:03.438Z"),
        "lastSessionsCollectionJobEntriesRefreshed" : 0,
        "lastSessionsCollectionJobEntriesEnded" : 0,
        "lastSessionsCollectionJobCursorsClosed" : 0,
        "transactionReaperJobCount" : 49566,
        "lastTransactionReaperJobDurationMillis" : 1,
        "lastTransactionReaperJobTimestamp" : ISODate("2021-02-28T17:03:17.631Z"),
        "lastTransactionReaperJobEntriesCleanedUp" : 0,
        "sessionCatalogSize" : 33
    },

发现问题后,我定期检查 config.system.sessions 中的多个会话。它从11k到560k不等(大部分时间在80k到350k之间),这似乎很高。 但是不管session多少,问题依旧。

突然出现错误,我们的负载和以前一样(我不知道我们以前有多少会话,但我们没有添加任何新客户端 - 我们有大约 3k 个连接。

没有分片,只有一个副本(一主一副)。

如果有任何关于如何解决此问题的建议,我将不胜感激。

UPD:另一件事对我来说很奇怪:

> db.system.sessions.count()
416068
> db.currentOp(true).inprog.length
2911

怎么会有这么大的差距?

您很可能需要在您的应用程序中进行一些调试,以找出泄漏会话的位置。

  1. 将驱动程序和服务器更新到最新版本。

  2. 确定您的应用程序在何处使用显式会话。显式会话是您通过 start_session 调用启动的会话。驱动程序本身也会自动使用会话,这些称为隐式会话。

  3. 没有相反的证据,你有一个会话泄漏。使用 https://docs.mongodb.com/manual/reference/command/killAllSessions/ 销毁所有会话,然后绘制活动会话数随时间变化的图表以查看您的趋势。

  4. 检查您的代码并将每个 start_session 调用与该会话的结束方式(如果有)相匹配。如果您不使用像 https://docs.mongodb.com/ruby-driver/master/tutorials/ruby-driver-sessions/#creating-a-session-from-a-mongo-client 这样的作用域 API,您需要仔细考虑每个会话将在何处被销毁。

  5. 检查您的代码是否没有超时游标。这些可能会保存会话引用(显式或隐式)。

根据您在问题中提供的信息,我猜您的会话状态检查没有正确完成,因此请再次检查并确保您查看的是正确的内容。