Я пытаюсь выполнить node.js с помощью mongodb (2.2.2), используя собственный накопитель node.js на 10gen.
Сначала все шло хорошо. Но, придя к эталонной части concurrency, произошло много ошибок. Частое соединение/закрытие с 1000 совпадений может привести к тому, что mongodb отклонит любые дополнительные запросы с ошибкой, например:Error: failed to connect to [localhost:27017]
Error: Could not locate any valid servers in initial seed list
Error: no primary server found in set
Кроме того, если многие клиенты закрываются без явного закрытия, для обнаружения и закрытия их потребуется mongodb минут. Это также вызовет аналогичные проблемы с подключением. (Используя/var/log/mongodb/mongodb.log, чтобы проверить состояние соединения)
Я много пробовал. Согласно руководству, mongodb не имеет ограничений на соединение, но параметр poolSize, по-видимому, не имеет для меня последствий.
Поскольку я работал с ним только в node -mongodb-native модуле, я не очень уверен, что в конечном итоге вызвало проблему. Как насчет производительности на других других языках и драйверах?
PS: В настоящее время использование автономного пула - единственное решение, которое я выяснил, но его использование не может решить проблему с набором реплик. Согласно моему тесту, набор реплик кажется гораздо менее подключенным, чем автономный mongodb. Но понятия не имею, почему это происходит.
Concurrency тестовый код:
var MongoClient = require('mongodb').MongoClient;
var uri = "mongodb://192.168.0.123:27017,192.168.0.124:27017/test";
for (var i = 0; i < 1000; i++) {
MongoClient.connect(uri, {
server: {
socketOptions: {
connectTimeoutMS: 3000
}
},
}, function (err, db) {
if (err) {
console.log('error: ', err);
} else {
var col = db.collection('test');
col.insert({abc:1}, function (err, result) {
if (err) {
console.log('insert error: ', err);
} else {
console.log('success: ', result);
}
db.close()
})
}
})
}
Решение с общим пулом:
var MongoClient = require('mongodb').MongoClient;
var poolModule = require('generic-pool');
var uri = "mongodb://localhost/test";
var read_pool = poolModule.Pool({
name : 'redis_offer_payment_reader',
create : function(callback) {
MongoClient.connect(uri, {}, function (err, db) {
if (err) {
callback(err);
} else {
callback(null, db);
}
});
},
destroy : function(client) { client.close(); },
max : 400,
// optional. if you set this, make sure to drain() (see step 3)
min : 200,
// specifies how long a resource can stay idle in pool before being removed
idleTimeoutMillis : 30000,
// if true, logs via console.log - can also be a function
log : false
});
var size = [];
for (var i = 0; i < 100000; i++) {
size.push(i);
}
size.forEach(function () {
read_pool.acquire(function (err, db) {
if (err) {
console.log('error: ', err);
} else {
var col = db.collection('test');
col.insert({abc:1}, function (err, result) {
if (err) {
console.log('insert error: ', err);
} else {
//console.log('success: ', result);
}
read_pool.release(db);
})
}
})
})