当前位置:  开发笔记 > 编程语言 > 正文

MongoDB连接的.NET最佳实践?

如何解决《MongoDB连接的.NET最佳实践?》经验,为你挑选了3个好方法。

我最近一直在使用GitHub上的C#驱动程序玩MongoDB(它的速度非常快).在我正在测试的小单线程控制台应用程序中,一切正常.我可以在8秒内运行单线程添加1,000,000个文档(是的,百万个).如果我使用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();

    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);
        }
    }
}

runxc1 Bret .. 102

这里的大多数答案都已过时,因为.net驱动程序已经成熟并添加了无数功能,因此不再适用.

查看此处的新2.0驱动程序的文档:http: //mongodb.github.io/mongo-csharp-driver/2.0/reference/driver/connecting/

.net驱动程序现在是线程安全的并处理连接池.根据文件

建议将MongoClient实例存储在全局位置,可以是静态变量,也可以是具有单例生存期的IoC容器.

该答案需要发送到顶部。接受我的投票! (2认同)


Joel Coehoor.. 9

关于静态连接要记住的是它在所有线程之间共享.你想要的是每个线程一个连接.



1> runxc1 Bret ..:

这里的大多数答案都已过时,因为.net驱动程序已经成熟并添加了无数功能,因此不再适用.

查看此处的新2.0驱动程序的文档:http: //mongodb.github.io/mongo-csharp-driver/2.0/reference/driver/connecting/

.net驱动程序现在是线程安全的并处理连接池.根据文件

建议将MongoClient实例存储在全局位置,可以是静态变量,也可以是具有单例生存期的IoC容器.


该答案需要发送到顶部。接受我的投票!

2> Joel Coehoor..:

关于静态连接要记住的是它在所有线程之间共享.你想要的是每个线程一个连接.


对于您的样本,您要对事物进行分组,每个线程一个是您可以做的最好的.一个静态的共享连接_will_会像你看到的那样创建死锁.您的替代方案是进行连接池.这是sql server提供程序内置的东西,但对于mongo,你必须自己构建,并且要做到正确并非易事.

3> Donny V...:

使用mongodb-csharp时,您会像处理ADO连接一样对待它.当你创建一个Mongo对象时,它借用了池所拥有的连接,直到它被处置为止.因此,在使用块之后,连接将重新进入池中.创建Mongo对象既便宜又快捷.

for(var i=0;i<100;i++) 
{ 
        using(var mongo1 = new Mongo()) 
        using(var mongo2 = new Mongo()) 
        { 
                mongo1.Connect(); 
                mongo2.Connect(); 
        } 
} 

数据库日志
Wed Jun 02 20:54:21连接从127.0.0.1:58214#1
Wed Jun 02 20:54:21连接从127.0.0.1:58215接受#2
Wed Jun 02 20:54:21 MessagingPort recv()错误:0无错误127.0.0.1:58214
Wed Jun 02 20:54:21 end connection 127.0.0.1:58214
Wed Jun 02 20:54:21 MessagingPort recv()errno:0 No error 127.0.0.1:58215
Wed Jun 02 20:54:21结束连接127.0.0.1:58215

请注意,它只打开了2个连接.

我把它放在一起使用mongodb-csharp论坛. http://groups.google.com/group/mongodb-csharp/browse_thread/thread/867fa78d726b1d4

推荐阅读
凹凸曼00威威_694
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有