我最近在使用GitHub上的C#驱动程序玩MongoDB(它快得惊人)。我的单线程控制台应用程序一切正常,我正在测试中。我能够在不到8秒的时间内添加100万个文档(是的,百万级别),但只有在连接超出for循环范围时才能获得这种性能。换句话说,在每次插入时保持连接打开,而不是为每次插入连接。显然这很牵强。
我想要进一步提高效率,看看它如何处理多个线程。我这样做是因为我需要模拟具有多个并发请求的网站。我同时启动15到50个线程,在所有情况下插入了总共150,000个文档。如果我让线程运行,每个线程创建一个新的连接进行每个插入操作,性能就会停滞不前。
显然,我需要找到一种共享、锁定或池化连接的方法。这就是问题所在。在连接MongoDB方面,什么是最佳实践?连接应该保持应用程序的生命周期开放(每个操作打开和关闭TCP连接的延迟很大)吗?
是否有任何与MongoDB以及特定底层连接相关的真实世界或生产经验?
这是我的线程示例,使用为插入操作锁定的静态连接。请提供在Web环境中最大化性能和可靠性的建议!
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);
}
}
}