为什么带有 topologyVersion 的 "hello" (isMaster) 命令超时?
Why are "hello" (isMaster) commands with topologyVersion timing out?
为了复制我在生产环境中看到的内容,我在本地有一个独立的 MongoDB 实例 运行ning,其中 hello()
管理命令(以前是 isMaster
) 运行s 直到 maxAwaitTimeMS
并且超时,每次:
db.runCommand({
"hello": 1,
"topologyVersion": {
"processId": ObjectId("628c762af984c948c15f8811"),
"counter": NumberLong(0)
},
"maxAwaitTimeMS": 5000,
"$db": "admin"
});;
请注意,当 'timing out' 时,响应仍然是客户端所期望的 - 不清楚的是为什么 Mongo 服务器没有立即 return,而不是让查询必须 运行 直到其 maxAwaitTimeMS
才能响应:
{
"isWritablePrimary" : true,
"topologyVersion" : {
"processId" : ObjectId("628c762af984c948c15f8811"),
"counter" : 0
},
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 100000,
"localTime" : ISODate("2022-05-29T11:35:36.011+01:00"),
"logicalSessionTimeoutMinutes" : 30,
"connectionId" : 86043,
"minWireVersion" : 0,
"maxWireVersion" : 9,
"readOnly" : false,
"ok" : 1
}
服务器上没有其他 activity - 因此这不是性能或连接问题,否则会被阻止。只要“awaitMaxTimeMS”,查询就会 运行,即使增加到例如 5 分钟也是如此。该问题仅发生在 topologyVersion
包含在调用中的情况下,特别是在使用正确的 processID
时,即在首次 运行 查询时 returned 时,如下所示:
// query completes immediately
db.runCommand({
"hello": 1,
"$db": "admin"
});
// and the response includes the following:
// { "processId" : ObjectId("628c762af984c948c15f8811") }
这些调用是由 Mongo 驱动程序(PyMongo 和 Ruby Mongo)发出的,我们在生产 [=40] 上看到了同样的问题=] 实例 - 其中 currentOp
显示许多 hello()
查询,所有这些查询都超时。
我的问题是,为什么这些请求超时并且没有按预期立即完成?
除了它在 currentOp
列表中产生的噪音(每个查询都停留 10 秒)以及理解原因的好奇心之外,我还希望解决这个问题以帮助确保连接正常否则由于这个问题而被搁置。减少 maxAwaitTimeMS
(假设 Mongo 驱动程序提供这样的控制)会让人觉得隐藏了问题。在复制的 MongoDB 服务器上执行一些测试时,问题似乎没有发生。
what's not clear is why the Mongo server does not return with this immediately, rather than having the query have to run till its maxAwaitTimeMS before responding:
这是称为流的 hello 线程的“特殊”模式的预期行为。简而言之,客户端只是通过发送一个 hello 命令来启动流服务器的状态,然后等待来自服务器的响应(不发送请求)。所以 maxAwaitTimeMS
是服务器在向客户端发送响应之前可以等待的最长时间。
所以是的,这是意料之中的。等待时间可以少于 maxAwaitTimeMS
,例如,如果服务器拓扑在等待期间已更改,但此值设置了最高等待界限,如果服务器健康,您将等待整个指定时间段
I see, so you're saying it's normal behaivour to have many isMaster/hello queries all running up to the maxAwaitTimeMS
如果它同时发生,那么我会投票认为它们在响应的 me
字段中包含不同的端点,因为驱动程序为每个端点创建了一个单独的 hello
线程
为了复制我在生产环境中看到的内容,我在本地有一个独立的 MongoDB 实例 运行ning,其中 hello()
管理命令(以前是 isMaster
) 运行s 直到 maxAwaitTimeMS
并且超时,每次:
db.runCommand({
"hello": 1,
"topologyVersion": {
"processId": ObjectId("628c762af984c948c15f8811"),
"counter": NumberLong(0)
},
"maxAwaitTimeMS": 5000,
"$db": "admin"
});;
请注意,当 'timing out' 时,响应仍然是客户端所期望的 - 不清楚的是为什么 Mongo 服务器没有立即 return,而不是让查询必须 运行 直到其 maxAwaitTimeMS
才能响应:
{
"isWritablePrimary" : true,
"topologyVersion" : {
"processId" : ObjectId("628c762af984c948c15f8811"),
"counter" : 0
},
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 100000,
"localTime" : ISODate("2022-05-29T11:35:36.011+01:00"),
"logicalSessionTimeoutMinutes" : 30,
"connectionId" : 86043,
"minWireVersion" : 0,
"maxWireVersion" : 9,
"readOnly" : false,
"ok" : 1
}
服务器上没有其他 activity - 因此这不是性能或连接问题,否则会被阻止。只要“awaitMaxTimeMS”,查询就会 运行,即使增加到例如 5 分钟也是如此。该问题仅发生在 topologyVersion
包含在调用中的情况下,特别是在使用正确的 processID
时,即在首次 运行 查询时 returned 时,如下所示:
// query completes immediately
db.runCommand({
"hello": 1,
"$db": "admin"
});
// and the response includes the following:
// { "processId" : ObjectId("628c762af984c948c15f8811") }
这些调用是由 Mongo 驱动程序(PyMongo 和 Ruby Mongo)发出的,我们在生产 [=40] 上看到了同样的问题=] 实例 - 其中 currentOp
显示许多 hello()
查询,所有这些查询都超时。
我的问题是,为什么这些请求超时并且没有按预期立即完成?
除了它在 currentOp
列表中产生的噪音(每个查询都停留 10 秒)以及理解原因的好奇心之外,我还希望解决这个问题以帮助确保连接正常否则由于这个问题而被搁置。减少 maxAwaitTimeMS
(假设 Mongo 驱动程序提供这样的控制)会让人觉得隐藏了问题。在复制的 MongoDB 服务器上执行一些测试时,问题似乎没有发生。
what's not clear is why the Mongo server does not return with this immediately, rather than having the query have to run till its maxAwaitTimeMS before responding:
这是称为流的 hello 线程的“特殊”模式的预期行为。简而言之,客户端只是通过发送一个 hello 命令来启动流服务器的状态,然后等待来自服务器的响应(不发送请求)。所以 maxAwaitTimeMS
是服务器在向客户端发送响应之前可以等待的最长时间。
所以是的,这是意料之中的。等待时间可以少于 maxAwaitTimeMS
,例如,如果服务器拓扑在等待期间已更改,但此值设置了最高等待界限,如果服务器健康,您将等待整个指定时间段
I see, so you're saying it's normal behaivour to have many isMaster/hello queries all running up to the maxAwaitTimeMS
如果它同时发生,那么我会投票认为它们在响应的 me
字段中包含不同的端点,因为驱动程序为每个端点创建了一个单独的 hello
线程