Недавно я играл с MongoDB (это удивительно FAST), используя драйвер С# на 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);
}
}
}