C# MongoDB 连接的 .NET 最佳实践?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2194047/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
.NET best practices for MongoDB connections?
提问by Tyler Brinks
I've been playing with MongoDB recently (It's AMAZINGLY FAST) using the C# driver on GitHub. Everything is working just fine in my little single threaded console app that I'm testing with. I'm able to add 1,000,000 documents (yes, million) in under 8 seconds running single threaded. I only get this performance if I use the connection outside the scope of a for loop. In other words, I'm keeping the connection open for each insert rather than connecting for each insert. Obviously that's contrived.
我最近一直在使用 GitHub 上的 C# 驱动程序玩 MongoDB(它非常快)。在我正在测试的小型单线程控制台应用程序中,一切正常。我能够在运行单线程的 8 秒内添加 1,000,000 个文档(是的,百万)。如果我在 for 循环范围之外使用连接,我只会获得这种性能。换句话说,我为每个插入保持连接打开,而不是为每个插入进行连接。显然这是人为的。
I thought I'd crank it up a notch to see how it works with multiple threads. I'm doing this because I need to simulate a website with multiple concurrent requests. I'm spinning up between 15 and 50 threads, still inserting a total of 150,000 documents in all cases. If I just let the threads run, each creating a new connection for each insert operation, the performance grinds to a halt.
我想我会把它调高一个档次,看看它是如何处理多线程的。我这样做是因为我需要模拟一个具有多个并发请求的网站。我在 15 到 50 个线程之间旋转,在所有情况下仍然插入总共 150,000 个文档。如果我只是让线程运行,每个线程为每个插入操作创建一个新连接,性能就会停滞不前。
Obviously I need to find a way to share, lock, or pool the connection. Therein lies the question. What's the best practice in terms of connecting to MongoDB? Should the connection be kept open for the life of the app (there is substantial latency opening and closing the TCP connection for each operation)?
显然,我需要找到一种方法来共享、锁定或池化连接。这就是问题所在。连接到 MongoDB 的最佳实践是什么?连接是否应该在应用程序的整个生命周期内保持打开状态(每次操作打开和关闭 TCP 连接都有相当大的延迟)?
Does anyone have any real world or production experience with MongoDB, and specifically the underlying connection?
有没有人对 MongoDB 有任何真实世界或生产经验,特别是底层连接?
Here is my threading sample using a static connection that's locked for insert operations. Please offer suggestions that would maximize performance and reliability in a web context!
这是我使用为插入操作锁定的静态连接的线程示例。请提供建议,以最大限度地提高 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);
}
}
}
回答by Joel Coehoorn
The thing to remember about a static connection is that it's shared among all your threads. What you want is one connection per thread.
关于静态连接要记住的事情是它在您的所有线程之间共享。您想要的是每个线程一个连接。
回答by ensecoz
Connection Pool should be your answer.
连接池应该是你的答案。
The feature is being developed (please see http://jira.mongodb.org/browse/CSHARP-9for more detail).
该功能正在开发中(有关更多详细信息,请参阅http://jira.mongodb.org/browse/CSHARP-9)。
Right now, for web application, the best practice is to connect at the BeginRequest and release the connection at EndRequest. But to me, I think that operation is too expensive for each request without Connection Pool. So I decide to have the global Mongo object and using that as shared resource for every threads (If you get the latest C# driver from github right now, they also improve the performance for concurrency a bit).
目前,对于 Web 应用程序,最佳实践是在 BeginRequest 连接并在 EndRequest 释放连接。但是对我来说,我认为对于没有连接池的每个请求来说,操作成本太高了。所以我决定拥有全局 Mongo 对象并将其用作每个线程的共享资源(如果您现在从 github 获得最新的 C# 驱动程序,它们也会稍微提高并发性能)。
I don't know the disadvantage for using Global Mongo object. So let's wait for another expert to comment on this.
我不知道使用 Global Mongo 对象的缺点。所以让我们等待另一位专家对此发表评论。
But I think I can live with it until the feature(Connection pool) have been completed.
但我认为在功能(连接池)完成之前我可以忍受它。
回答by David Robbins
Somewhat but still of interest is CSMongo,a C# driver for MongoDB created by the developer of jLinq. Here's a sample:
有点但仍然令人感兴趣的是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);
}
回答by Donny V.
When using mongodb-csharp you treat it like you would an ADO connection. When you create a Mongo object it borrows a connection from the pool, which it owns until it is disposed. So after the using block the connection is back into the pool. Creating Mongo objects are cheap and fast.
使用 mongodb-csharp 时,您可以像对待 ADO 连接一样对待它。当您创建一个 Mongo 对象时,它会从池中借用一个连接,该连接在被释放之前一直属于它所有。所以在使用块之后,连接又回到了池中。创建 Mongo 对象既便宜又快速。
Example
例子
for(var i=0;i<100;i++)
{
using(var mongo1 = new Mongo())
using(var mongo2 = new Mongo())
{
mongo1.Connect();
mongo2.Connect();
}
}
Database Log
Wed Jun 02 20:54:21 connection accepted from 127.0.0.1:58214 #1
Wed Jun 02 20:54:21 connection accepted from 127.0.0.1:58215 #2
Wed Jun 02 20:54:21 MessagingPort recv() errno:0 No error 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 end connection 127.0.0.1:58215
数据库日志
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
星期三6月2日20时54分21秒结束连接127.0.0.1:58214
星期三6月2日20时54分21秒MessagingPort的recv()错误号:0无错误127.0.0.1:58215
星期三6月2日20:54:21 结束连接 127.0.0.1:58215
Notice it only opened 2 connections.
注意它只打开了 2 个连接。
I put this together using mongodb-csharp forum. http://groups.google.com/group/mongodb-csharp/browse_thread/thread/867fa78d726b1d4
我使用 mongodb-csharp 论坛将它们放在一起。 http://groups.google.com/group/mongodb-csharp/browse_thread/thread/867fa78d726b1d4
回答by Antony Blazer
I am using csharp-mongodb driver and it doesn't help me with his connection pool :( I have about 10-20 request to mongodb per web request.(150 users online - average) And i can't even monitor statistics or connect to mongodb from shell it throw exception to me.
我正在使用 csharp-mongodb 驱动程序,但它对我的连接池没有帮助:( 每个 Web 请求我有大约 10-20 个对 mongodb 的请求。(150 个用户在线 - 平均)而且我什至无法监控统计信息或连接从 shell 到 mongodb 它向我抛出异常。
I have created repository, which open and dispose connection per request. I rely on such things as: 1) Driver has connection pool 2) After my research(i have posted some question in user groups about this) - i understood that creating mongo object and open connection doesn't heavy operation, so heavy operation.
我创建了存储库,它根据请求打开和处理连接。我依赖于这样的东西:1)驱动程序有连接池 2)经过我的研究(我在用户组中发布了一些关于这个的问题) - 我明白创建 mongo 对象和打开连接并不需要繁重的操作,所以繁重的操作。
But today my production go down :( May be i have to save open connection per request...
但是今天我的生产下降了 :( 可能是我必须为每个请求保存打开的连接...
here is link to user group http://groups.google.com/group/mongodb-user/browse_thread/thread/3d4a4e6c5eb48be3#
这是用户组的链接http://groups.google.com/group/mongodb-user/browse_thread/thread/3d4a4e6c5eb48be3#
回答by runxc1 Bret Ferrier
Most answers here are outdatedand are no longer applicable as the .net driver has matured and had numberless features added.
这里的大多数答案已经过时,不再适用,因为 .net 驱动程序已经成熟并添加了无数功能。
Looking at the documentation of the new 2.0 driver found here: http://mongodb.github.io/mongo-csharp-driver/2.0/reference/driver/connecting/
查看此处找到的新 2.0 驱动程序的文档:http: //mongodb.github.io/mongo-csharp-driver/2.0/reference/driver/connecting/
The .net driver is now thread safe and handles connection pooling. According to documentation
.net 驱动程序现在是线程安全的并处理连接池。根据文档
It is recommended to store a MongoClient instance in a global place, either as a static variable or in an IoC container with a singleton lifetime.
建议将 MongoClient 实例存储在全局位置,作为静态变量或具有单例生命周期的 IoC 容器。