.NET MongoDB 连接的最佳实践?

     2023-02-16     181

关键词:

【中文标题】.NET MongoDB 连接的最佳实践?【英文标题】:.NET best practices for MongoDB connections? 【发布时间】:2011-01-12 17:40:48 【问题描述】:

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

【问题讨论】:

你最后做了什么决定?面临同样的问题... 好消息是我不必做决定。 Mongodb-csharp 和 NoRM 驱动程序都添加了对连接池的支持。这两个库都有精心设计的线程安全机制,用于针对 mongod 或 mongos 进程池连接。这两个领域也在不久的将来增加了对副本集的支持。 @TylerBrinks 你能举例说明如何在 8 秒内插入 1m 个文档吗?我无法在单线程上达到那个速度。 【参考方案1】:

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

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

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

建议将 MongoClient 实例存储在全局位置,作为静态变量或具有单例生命周期的 IoC 容器。

【讨论】:

这个答案需要发送到顶部。接受我的投票!【参考方案2】:

我正在使用 csharp-mongodb 驱动程序,但它对我的连接池没有帮助:(每个 Web 请求我对 mongodb 大约有 10-20 个请求。(150 个用户在线 - 平均)而且我什至无法监控统计数据或从 shell 连接到 mongodb 它会向我抛出异常。

我已经创建了存储库,它根据请求打开和处理连接。我依靠这样的东西: 1)驱动有连接池 2)经过我的研究(我在用户组中发布了一些关于此的问题) - 我了解到创建 mongo 对象和打开连接不会繁重的操作,所以繁重的操作。

但是今天我的产量下降了:( 可能我必须为每个请求保存打开的连接...

这里是用户组http://groups.google.com/group/mongodb-user/browse_thread/thread/3d4a4e6c5eb48be3#的链接

【讨论】:

如果你释放你的连接,你实际上是在与连接池对抗——连接池不能回收一个释放的连接,并且必须为每个请求建立一个全新的连接的开销。只需使用您的连接,完成后将其关闭。【参考方案3】:

在使用 mongodb-csharp 时,您可以像对待 ADO 连接一样对待它。 当你创建一个 Mongo 对象时,它会从池中借用一个连接,直到它被释放为止。因此,在 using 块之后,连接又回到了池中。 创建 Mongo 对象既便宜又快速。

示例

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

数据库日志从 127.0.0.1:58214 #1 接受的连接于 6 月 2 日星期三 20:54:21 6 月 2 日星期三 20:54:21 接受来自 127.0.0.1:58215 #2 的连接 6 月 2 日星期三 20:54:21 MessagingPort recv() errno:0 没有错误 127.0.0.1:58214 6 月 2 日星期三 20:54:21 结束连接 127.0.0.1:58214 6 月 2 日星期三 20:54:21 MessagingPort recv() errno:0 没有错误 127.0.0.1:58215 6 月 2 日星期三 20:54:21 结束连接 127.0.0.1:58215

注意它只打开了 2 个连接。

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

【讨论】:

迄今为止的最佳答案。谢谢! :)【参考方案4】:

CSMongo, 是一个由 jLinq 的开发人员创建的 MongoDB 的 C# 驱动程序,但仍然令人感兴趣。这是一个示例:

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


【讨论】:

【参考方案5】:

连接池应该是你的答案。

该功能正在开发中(详情请参阅http://jira.mongodb.org/browse/CSHARP-9)。

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

我不知道使用 Global Mongo 对象的缺点。所以让我们等待另一位专家对此发表评论。

但我认为在功能(连接池)完成之前我可以忍受它。

【讨论】:

您是否使用相同的方式连接到 SQL Server/MySQL?我认为连接池的最佳实践仍然是“迟开早关”,并且在请求期间多次打开/关闭连接几乎没有任何成本。【参考方案6】:

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

【讨论】:

您可能错过了我所说的每个线程一个连接明显慢的部分。我认为这不是高流量网站的最佳答案。 对于您的示例,您在其中对事物进行分组,每个线程一个是您能做的最好的。一个静态的共享连接像你看到的那样创建死锁。您的替代方法是进行连接池。这是 sql server 提供程序内置的东西,但对于 mongo,您必须自己构建,而且要做好并非易事。 今天再看这个,也有可能是你的线程太多了。理想情况下,您需要为您的工作项目创建一个共享的、线程安全的队列,并且只有少数几个线程(具体数量取决于您的系统,但最大的因素是处理器内核的数量)。每个线程从队列中拉取项目。这将减少连接的数量,因此它们不再是瓶颈。

Node.js 上 MongoDB 连接的最佳实践是啥?

】Node.js上MongoDB连接的最佳实践是啥?【英文标题】:What\'sthebestpracticeforMongoDBconnectionsonNode.js?Node.js上MongoDB连接的最佳实践是什么?【发布时间】:2012-08-0118:02:48【问题描述】:这对我来说有点不清楚(我刚刚开始使用Node和Mongo... 查看详情

mongodb最佳实践经验总结

                    查看详情

在 Mongodb 中存储价格随时间变化的最佳实践

】在Mongodb中存储价格随时间变化的最佳实践【英文标题】:BestpracticetostorepricechangesovertimeinMongodb【发布时间】:2022-01-2100:29:11【问题描述】:我使用Nestjs和Mongoose作为ODM。我有一个名为Product的模型,它具有以下属性:产品型号@S... 查看详情

.Net WCF NAT 遍历的最佳实践

...解决方案。假设我有一个聊天应用程序,两个客户端需要连接,但都在NAT后面:对于家庭场景,uPNP可能没问题,因为只涉及电缆调制解调器或消费者路由器。但是,无法实现uPNP的企业环境呢?我熟悉UDP打孔,它可以用 查看详情

MongoDB / Mongoose 单元测试 - 最佳实践? [关闭]

】MongoDB/Mongoose单元测试-最佳实践?[关闭]【英文标题】:MongoDB/MongooseUnitTesting-Bestpractice?[closed]【发布时间】:2015-03-2911:10:42【问题描述】:我正在编写一个npm包,通过mongoose将GIS数据导入MongoDB。我已经使用mocha编写了单元测试... 查看详情

Lucene.Net 最佳实践

】Lucene.Net最佳实践【英文标题】:Lucene.NetBestPractices【发布时间】:2010-11-0309:18:28【问题描述】:使用Lucene.Net的最佳实践是什么?或者我在哪里可以找到一个好的lucene.net使用示例?【问题讨论】:【参考方案1】:如果您打算使... 查看详情

实体框架和 ASP.NET 的最佳实践

】实体框架和ASP.NET的最佳实践【英文标题】:BestPracticesforEntityFrameworkandASP.NET【发布时间】:2010-09-1422:42:59【问题描述】:我一直让自己发疯,试图让实体框架在ASP.NET环境中按预期(或至少按我预期)工作,特别是在尝试保存... 查看详情

在 .Net 中使用扩展方法的最佳实践是啥?

】在.Net中使用扩展方法的最佳实践是啥?【英文标题】:WhatarethebestpracticesforusingExtensionMethodsin.Net?在.Net中使用扩展方法的最佳实践是什么?【发布时间】:2010-09-0509:54:18【问题描述】:我已经看到这些被以各种方式使用,并被... 查看详情

表的 ASP.NET 最佳实践

】表的ASP.NET最佳实践【英文标题】:ASP.NETBestPracticeforTable【发布时间】:2020-04-1918:24:37【问题描述】:我正在处理一个ASP.NETCore项目,该项目有一个表,我根据它们所在的当前选项卡对其进行过滤。我最初的想法是使用JSON调用C#... 查看详情

.NET Core 3.1 + GraphQL + MongoDB

】.NETCore3.1+GraphQL+MongoDB【英文标题】:【发布时间】:2020-06-1823:57:36【问题描述】:对于基于文档的数据库和.NET堆栈的GraphQL,是否有任何实现示例/最佳实践/文档?我正在将MongoDB与.NETCore3.1一起使用,我会考虑从REST切换到GraphQL... 查看详情

捕获和重新抛出 .NET 异常的最佳实践

】捕获和重新抛出.NET异常的最佳实践【英文标题】:Bestpracticesforcatchingandre-throwing.NETexceptions【发布时间】:2010-09-0613:29:45【问题描述】:在捕获异常并重新抛出异常时要考虑哪些最佳做法?我想确保保留Exception对象的InnerExceptio... 查看详情

在 ASP.NET 上启动维护过程的最佳实践是啥 [关闭]

】在ASP.NET上启动维护过程的最佳实践是啥[关闭]【英文标题】:WhatistheBestPracticetoKick-offMaintenanceProcessonASP.NET[closed]在ASP.NET上启动维护过程的最佳实践是什么[关闭]【发布时间】:2008-09-0513:38:12【问题描述】:给定一个ASP.NET应用... 查看详情

mongo实战之数据空洞的最佳实践(代码片段)

问题背景:某天,开发部的同事跑过来反映:mongodb数据文件太大,快把磁盘撑爆了!其中某个db占用最大(运营环境这个db的数据量其实很小)分析:开发环境有大量测试的增/删/改操作,而由于MongoDB顺序写的原因,在我们删除部分无用... 查看详情

连接/断开数据库的最佳实践是啥?

】连接/断开数据库的最佳实践是啥?【英文标题】:Whatisthebestpracticetoconnect/disconnecttoadatabase?连接/断开数据库的最佳实践是什么?【发布时间】:2016-04-0602:48:42【问题描述】:我想知道如何在MEAN堆栈应用程序中使用与数据库的... 查看详情

连接/断开数据库的最佳实践是啥?

】连接/断开数据库的最佳实践是啥?【英文标题】:Whatisthebestpracticetoconnect/disconnecttoadatabase?连接/断开数据库的最佳实践是什么?【发布时间】:2016-04-0602:48:42【问题描述】:我想知道如何在MEAN堆栈应用程序中使用与数据库的... 查看详情

C# 数据连接最佳实践?

】C#数据连接最佳实践?【英文标题】:C#DataConnectionsBestPractice?【发布时间】:2013-07-0707:57:16【问题描述】:好的,这是一种固执己见的话题,但根据您的知识、观点和当前实践,设置以下场景的最佳方法是什么?我正在构建一... 查看详情

在 .NET 应用程序中保留配置/用户信息的最佳实践 [重复]

】在.NET应用程序中保留配置/用户信息的最佳实践[重复]【英文标题】:Bestpracticetopersistconfig/userinfoin.NETapp[duplicate]【发布时间】:2010-11-0413:27:36【问题描述】:我的.NET应用程序中要保留的数据量很少。例如,上次用户在附近时... 查看详情

带有 HttpClientFactory 的 ASP.NET Core:最佳实践?

】带有HttpClientFactory的ASP.NETCore:最佳实践?【英文标题】:ASP.NETCorewithHttpClientFactory:bestpractice?【发布时间】:2021-12-0921:16:16【问题描述】:我有一个需要循环调用Web服务的ASP.NETCore应用程序。我实例化了一个HostedService:publicclas... 查看详情