Javascript MongoDB拒绝大容量(10000)插入/写入的连接
我们正在通过Node.js应用程序插入数据,并使用该库连接到mongodb。 Mongo DB共分为5个分片。节点和mongos实例包含在一个四核AWS实例上,该实例具有14980MB的RAM。有两个碎片和配置服务器 包含在单核实例中,其余三个碎片位于具有单核处理器的不同实例上 使用Node.js测试脚本,我们可以在9秒内有效地并发插入1000条记录 对于10000个并发插入,大约2000个插入失败并返回以下错误消息:Javascript MongoDB拒绝大容量(10000)插入/写入的连接,javascript,node.js,mongodb,Javascript,Node.js,Mongodb,我们正在通过Node.js应用程序插入数据,并使用该库连接到mongodb。 Mongo DB共分为5个分片。节点和mongos实例包含在一个四核AWS实例上,该实例具有14980MB的RAM。有两个碎片和配置服务器 包含在单核实例中,其余三个碎片位于具有单核处理器的不同实例上 使用Node.js测试脚本,我们可以在9秒内有效地并发插入1000条记录 对于10000个并发插入,大约2000个插入失败并返回以下错误消息: [Error: failed to connect to [ip a
[Error: failed to connect to [ip address of mongos]]
在这10000次插入过程中,前5000次或6000次插入成功,没有错误。
在此期间,CPU使用率保持相对较低(13%的使用率)。然后一个核心上的CPU跳到大约75%,MongoDB抛出
拒绝连接的错误消息。插入失败后,某些写入操作会间歇性成功
我们在linux上将ulimit-n设置为20000。我们已经在Node.js api中的insert函数中传递了poolSize=5参数
var responseHandlers = require('./responseHandlers')
,schemaValidation = require('./schemaValidation')
,mongoDb = require('mongodb')
,md5 = require('MD5')
,ObjectID = require('mongodb').ObjectID;
function insert(data, timestamp, response) {
// validating the data to be inserted
schemaValidation.validate(data, function(err) {
if(err) {
console.log(err);
responseHandlers.invalidRequest(response, 2);
} else {
//console.log("opening db..");
server = new mongoDb.Server(mongoConfig.host,mongoConfig.port,{'auto_reconnect': true, 'poolSize': 5});
db = new mongoDb.Db(mongoConfig.database, server, {w: 1});
db.open(function(err, db) {
if(err) {
console.log(err);
responseHandlers.invalidRequest(response, 2);
} else {
db.collection(mongoConfig.collection, function(err, collection) {
if(err) {
console.log(err);
responseHandlers.invalidRequest(response, 2);
} else {
//going to instantiate document fields
var time = new Date().getTime(),
oid = new ObjectID(),
hash = md5(oid.toHexString()),
obj = {'data_utc' : timestamp, 'server_utc' : time, '_id' : oid, 'hash' : hash};
obj.data = data;
//inserting..
collection.insert(obj, {w:1}, function(err, result) {
if(err) {
console.log(err);
responseHandlers.invalidRequest(response, 2);
} else {
console.log('Insert successful');
responseHandlers.validRequest(response, false, result);
}
db.close();
});
}
});
}
});
}
});
}
exports.insert = insert;
有谁能帮我解释一下为什么它会拒绝连接,无法插入?它为什么有效
对于一部分插入,然后在中途失败?要解决此问题,您应该观察mongod控制台中打开的连接数。根据您提供的代码示例,您可能会在每次插入时打开一个新的mongodb连接。若要更正此问题,请尝试将“服务器”的实例化移动到用于调用此函数的控制循环范围之外。似乎在循环中创建了太多连接。最好的方法是创建mongoDB客户端的Singleton实例,并在集合中的每次更新和插入都使用相同的对象。 MongoDB对连接池有限制,默认大小为5个连接。之后的任何尝试都将拒绝服务器,但是您可以增加默认连接池大小,但这样做不是一个好主意。
另一点需要注意的是,MongoDB:在执行并发写入的线程数量有限的情况下性能更好。对于集合中的写入(使用最新的驱动程序3.2),mongoDB对集合执行行级锁定。它一次获取1000条记录的锁,并在更新记录时滑动锁。所以,若您放置更多并发线程来执行并行操作,它最终将等待锁被释放。最好使用2个线程进行写操作,或者最大使用4个线程,块大小为20k或40K 您可以考虑为受控读写实现生产者/消费者模式
有关详细信息,请参见此处:是否为每个插入创建一台服务器(池大小为5),即创建10000 db连接?