Mongodb服务器套接字closuresreplSet

当我们进行大量的并行连接时,我们遇到了closuresmongodb套接字的问题。

这是一个testing脚本:

var mongodb = require("mongodb"); var async = require("async"); mongodb.MongoClient.connect("mongodb://mongo-dev1:27017/test", function(err, db) { if (err) { throw err; } var calls = []; var col = db.collection("test"); var count = 10000; for(var i = 0; i < count; i++) { (function(i) { calls.push(function(cb) { console.time("update_" + i); col.update({ i : i }, { i : i }, { upsert : true }, function(err) { console.timeEnd("update_" + i); cb(err); }); }); })(i); } async.parallel(calls, function(err) { if (err) { throw err; } console.log("done"); }); }); 

如果我运行该脚本,将失败,并出现以下错误MongoError: server mongo-dev1:27017 sockets closed

从MongoDB本身输出的日志是

SocketException handling request, closing client connection: 9001 socket exception [SEND_ERROR] server [192.168.1.111:53556]

我无法弄清楚是什么机制导致套接字closures。 我相信,等式的节点端是挂起的,因为我的事件计时显示在mongodb日志中发生SocketException之前的毫秒发生节点closures事件。 我进入mongodb包进入mongodb-core并做了一些console.log和事件的发起者at TCP.close (net.js:485:12) 。 这告诉我,套接字本身正在closures。 基于这一点,它真的感觉就像linux本身正在closures套接字或mongoDB主机框,而不是Node或MongoDB这样做。 我不知道如何certificate这一点。

这是我考虑的第一套选项,但已经排除了:

  1. 套接字超时 – 如果是超时,错误信息是不同的,我通过传递socketTimeoutMS选项,当我构build连接来validation。 如果我通过一些小事,我会得到超时错误。

  2. MongoDB断开连接 – 如果我使用db.serverStatus().connections监视mongodb replset db.serverStatus().connections我仍然有很多可用的连接。

  3. 当我与本地主机非副本集进行通信时,此行为不会复制。 这可能是一个本地的东西,或者它可能是一个副本设置的事情。

  4. 如果我将并行更改为parallelLimit为100,则完成时没有问题。 由于Node使用了一个连接池,无论我是并行发送1000个还是并行发送100个,它应该等于MongoDB的stream量,因为它们都被强制进入相同的10个套接字。 这有助于指导我这是一个节点问题。

使用节点10,节点12和MongoDB 2.6

我在重负载下遇到了同样的问题,但是在挖掘mongodb驱动程序时,我发现socketTimeout和connectTimeout的默认值设置为30000毫秒。

提高他们都解决了我的问题:

 mongodb://m1.url.xyz:27017,m2.url.xyz:27017/test?replicaSet=myset&connectTimeoutMS=300000&socketTimeoutMS=300000&readPreference=secondary 

(请确保ulimit设置和net.ipv4.tcp_keepalive_time已针对mongodb进行了优化) http://docs.mongodb.org/manual/faq/diagnostics/

连接到networking上的副本集并在数据库初始化脚本中快速发出大量查询时,我遇到了同样的问题。

当在同一台计算机上连接到一个单一的mongodb实例时,它是正常的,但通过一个networking,甚至只有2-3毫秒的延迟副本集,它会抛出套接字closures错误。

我还将两台计算机上的保持活动时间更改为registry中的120。 MongoDB 3.0.6服务器在Windows Server 2012上,应用程序机器在Windows 10上。

然后我试了一下,没有任何效果(首先在副本集上重新启动了mongod服务)

然后我将?connectTimeoutMS=120000&socketTimeoutMS=120000部分添加到查询string中,并且使用Replica ?connectTimeoutMS=120000&socketTimeoutMS=120000了networking。

当我查看选项的文档时,发现单个实例服务器的默认超时值为30000ms,但对于副本集 ,缺省值为0ms

在: http : //mongodb.github.io/node-mongodb-native/2.1/reference/connecting/connection-settings/

请参阅:复制副本级别选项

socketOptions.connectTimeoutMS {Number, default: 0} TCP Connection timeout setting. socketOptions.socketTimeoutMS {Number, default: 0} TCP Socket timeout setting.

这是node.js驱动程序的文档。 我找不到有关套接字和连接超时的mongoose文档的信息只有其他选项。 我目前假设mongoose会通过你指定的选项通过逐字,而不是白名单只有某些选项。 那么您可以在选项对象中指定超时而不是连接string。