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'}
。
我们使用的任何连接驱动程序都会发生这种情况:
- Mongo shell
- pymongo 3.6
- pymongo 3.11
并不是每个查询都会发生,但大约占所有查询的 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
怎么会有这么大的差距?
您很可能需要在您的应用程序中进行一些调试,以找出泄漏会话的位置。
将驱动程序和服务器更新到最新版本。
确定您的应用程序在何处使用显式会话。显式会话是您通过 start_session 调用启动的会话。驱动程序本身也会自动使用会话,这些称为隐式会话。
没有相反的证据,你有一个会话泄漏。使用 https://docs.mongodb.com/manual/reference/command/killAllSessions/ 销毁所有会话,然后绘制活动会话数随时间变化的图表以查看您的趋势。
检查您的代码并将每个 start_session 调用与该会话的结束方式(如果有)相匹配。如果您不使用像 https://docs.mongodb.com/ruby-driver/master/tutorials/ruby-driver-sessions/#creating-a-session-from-a-mongo-client 这样的作用域 API,您需要仔细考虑每个会话将在何处被销毁。
检查您的代码是否没有超时游标。这些可能会保存会话引用(显式或隐式)。
根据您在问题中提供的信息,我猜您的会话状态检查没有正确完成,因此请再次检查并确保您查看的是正确的内容。
在连接到 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'}
。
我们使用的任何连接驱动程序都会发生这种情况:
- Mongo shell
- pymongo 3.6
- pymongo 3.11
并不是每个查询都会发生,但大约占所有查询的 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
怎么会有这么大的差距?
您很可能需要在您的应用程序中进行一些调试,以找出泄漏会话的位置。
将驱动程序和服务器更新到最新版本。
确定您的应用程序在何处使用显式会话。显式会话是您通过 start_session 调用启动的会话。驱动程序本身也会自动使用会话,这些称为隐式会话。
没有相反的证据,你有一个会话泄漏。使用 https://docs.mongodb.com/manual/reference/command/killAllSessions/ 销毁所有会话,然后绘制活动会话数随时间变化的图表以查看您的趋势。
检查您的代码并将每个 start_session 调用与该会话的结束方式(如果有)相匹配。如果您不使用像 https://docs.mongodb.com/ruby-driver/master/tutorials/ruby-driver-sessions/#creating-a-session-from-a-mongo-client 这样的作用域 API,您需要仔细考虑每个会话将在何处被销毁。
检查您的代码是否没有超时游标。这些可能会保存会话引用(显式或隐式)。
根据您在问题中提供的信息,我猜您的会话状态检查没有正确完成,因此请再次检查并确保您查看的是正确的内容。