Я недавно играл с MongoDB (это ИЗУМИТЕЛЬНО БЫСТРО), используя драйвер C # на GitHub. Все отлично работает в моем маленьком однопоточном консольном приложении, с которым я тестирую. Я могу добавить 1 000 000 документов (да, миллион) менее чем за 8 секунд, работая однопоточным. Я получаю эту производительность только в том случае, если я использую соединение за пределами цикла for. Другими словами, я сохраняю соединение открытым для каждой вставки, а не для каждой вставки. Очевидно, что это выдумано.
Я подумал, что проверю это на ступеньку выше, чтобы увидеть, как оно работает с несколькими потоками. Я делаю это, потому что мне нужно смоделировать веб-сайт с несколькими одновременными запросами. Я раскручиваю от 15 до 50 потоков, все еще вставляя 150 000 документов во всех случаях. Если я просто разрешу запускать потоки, каждый из которых создает новое соединение для каждой операции вставки, производительность останавливается.
Очевидно, мне нужно найти способ поделиться, заблокировать или объединить соединение. В этом и заключается вопрос. Какова лучшая практика с точки зрения подключения к MongoDB? Должно ли соединение оставаться открытым в течение всего срока службы приложения (при каждой операции открытия и закрытия TCP-соединения возникают значительные задержки)?
Есть ли у кого-нибудь опыт работы с MongoDB в реальном мире или на производстве, и, в частности, основное подключение?
Вот мой пример потоков, использующий статическое соединение, заблокированное для операций вставки. Пожалуйста, предлагайте предложения, которые максимизируют производительность и надежность в веб-контексте!
private static Mongo _mongo;
private static void RunMongoThreaded()
{
_mongo = new Mongo();
_mongo.Connect();
var threadFinishEvents = new List<EventWaitHandle>();
for(var i = 0; i < 50; i++)
{
var threadFinish = new EventWaitHandle(false, EventResetMode.ManualReset);
threadFinishEvents.Add(threadFinish);
var thread = new Thread(delegate()
{
RunMongoThread();
threadFinish.Set();
});
thread.Start();
}
WaitHandle.WaitAll(threadFinishEvents.ToArray());
_mongo.Disconnect();
}
private static void RunMongoThread()
{
for (var i = 0; i < 3000; i++)
{
var db = _mongo.getDB("Sample");
var collection = db.GetCollection("Users");
var user = GetUser(i);
var document = new Document();
document["FirstName"] = user.FirstName;
document["LastName"] = user.LastName;
lock (_mongo) // Lock the connection - not ideal for threading, but safe and seemingly fast
{
collection.Insert(document);
}
}
}