Я пробую node.js с mongodb (2.2.2) вместе, используя родной node.js диск на 10gen.Каков правильный способ работы с соединениями Mongodb?
Сначала все шло хорошо. Но, когда мы приходили к параллельной сравнительной части, происходило много ошибок. Частый Соединить/близко с 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. Но понятия не имею, почему это происходит.
Параллелизм код теста:
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()
})
}
})
}
решение Generic бассейн:
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);
})
}
})
})
Хотя Node.js использует единый процесс и модель событий, но IO действия всегда должны быть асинхронными. Я думаю, это не может быть причиной моих проблем. Но, я попробую, как вы цитировали, спасибо. – Jack
Вам не хватает точки в первом примере; Этот код эквивалентен началу вашего приложения Mongo 1000 раз. Вы должны только позвонить .connect один раз в своем приложении. –
Да, это проблема, и причина в том, что MongoClient имеет пул соединений, который становится дороже других dbs. Но не проблема с единственной технологической моделью node.js. – Jack