首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >MongoDB连接的.NET最佳实践?

MongoDB连接的.NET最佳实践?
EN

Stack Overflow用户
提问于 2010-02-04 01:42:13
回答 4查看 33K关注 0票数 71

我最近一直在玩MongoDB (它的速度非常快),使用的是GitHub上的C#驱动。在我正在测试的小单线程控制台应用程序中,一切都运行良好。我能够在单线程运行的8秒内添加1,000,000个文档(是的,上百万个)。只有当我在for循环的作用域之外使用连接时,我才能获得这种性能。换句话说,我为每个插入保持连接打开,而不是为每个插入保持连接。很明显,这是人为的。

我想我应该把它提高一个档次,看看它在多线程下是如何工作的。我这样做是因为我需要模拟一个具有多个并发请求的网站。我在15到50个线程之间旋转,仍然在所有情况下插入总共150,000个文档。如果我只是让线程运行,每个线程都为每个插入操作创建一个新连接,性能就会陷入停顿。

显然,我需要找到一种方法来共享、锁定或池化连接。这就是问题所在。就连接到MongoDB而言,最佳实践是什么?连接是否应该在应用程序的生命周期内保持打开(每次操作打开和关闭TCP连接都会有相当大的延迟)?

有没有人有过使用MongoDB,特别是底层连接的实际经验或生产经验?

下面是我使用静态连接的线程示例,该静态连接被锁定以进行插入操作。请提供在web环境中最大限度地提高性能和可靠性的建议!

代码语言:javascript
复制
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);
        }
    }
}
EN

回答 4

Stack Overflow用户

发布于 2010-02-04 01:47:18

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

票数 9
EN

Stack Overflow用户

发布于 2010-03-07 20:34:11

在某种程度上,但仍然令人感兴趣的是CSMongo,,它是由jLinq的开发人员为MongoDB创建的C#驱动程序。下面是一个示例:

代码语言:javascript
复制
//create a database instance
using (MongoDatabase database = new MongoDatabase(connectionString)) {

    //create a new document to add
    MongoDocument document = new MongoDocument(new {
        name = "Hugo",
        age = 30,
        admin = false
    });

    //create entire objects with anonymous types
    document += new {
        admin = true,
        website = "http://www.hugoware.net",
        settings = new {
            color = "orange",
            highlight = "yellow",
            background = "abstract.jpg"
        }
    };

    //remove fields entirely
    document -= "languages";
    document -= new[] { "website", "settings.highlight" };

    //or even attach other documents
    MongoDocument stuff = new MongoDocument(new {
        computers = new [] { 
            "Dell XPS", 
            "Sony VAIO", 
            "Macbook Pro" 
            }
        });
    document += stuff;

    //insert the document immediately
    database.Insert("users", document);

}
票数 1
EN

Stack Overflow用户

发布于 2010-03-07 20:23:46

连接池应该是您的答案。

该功能正在开发中(请参阅http://jira.mongodb.org/browse/CSHARP-9了解更多详细信息)。

目前,对于web应用程序,最佳实践是在BeginRequest处连接,然后在EndRequest处释放连接。但对我来说,我认为对于没有连接池的每个请求来说,操作成本太高了。所以我决定使用全局Mongo对象,并将其作为每个线程的共享资源(如果您现在从github获得最新的C#驱动程序,它们也会提高一点并发性能)。

我不知道使用Global Mongo object有什么缺点。因此,让我们等待另一位专家对此发表评论。

但我认为我可以接受它,直到功能(连接池)完成。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2194047

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档