簡體   English   中英

MongoDB連接的.NET最佳實踐?

[英].NET best practices for MongoDB connections?

我最近一直在使用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<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);
        }
    }
}

這里的大多數答案都已過時 ,因為.net驅動程序已經成熟並添加了無數功能,因此不再適用。

查看此處的新2.0驅動程序的文檔: http//mongodb.github.io/mongo-csharp-driver/2.0/reference/driver/connecting/

.net驅動程序現在是線程安全的並處理連接池。 根據文件

建議將MongoClient實例存儲在全局位置,可以是靜態變量,也可以是具有單例生存期的IoC容器。

關於靜態連接要記住的是它在所有線程之間共享。 你想要的是每個線程一個連接。

使用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(); 
        } 
} 

數據庫日志
2月2日星期三20:54:21從127.0.0.1:58214#1接受連接
2月2日星期三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()錯誤號碼:0無錯誤127.0.0.1:58215
Wed Jun 02 20:54:21 end connection 127.0.0.1:58215

請注意,它只打開了2個連接。

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

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

}

連接池應該是你的答案。

該功能正在開發中(有關更多詳細信息,請參閱http://jira.mongodb.org/browse/CSHARP-9 )。

現在,對於Web應用程序,最佳做法是在BeginRequest上連接並在EndRequest上釋放連接。 但對我來說,我認為對於沒有連接池的每個請求,操作太昂貴了。 所以我決定使用全局Mongo對象並將其用作每個線程的共享資源(如果你現在從github獲得最新的C#驅動程序,它們也會提高並發性能)。

我不知道使用Global Mongo對象的缺點。 所以讓我們等待另一位專家對此發表評論。

但我認為我可以忍受它,直到功能(連接池)完成。

我正在使用csharp-mongodb驅動程序,它沒有幫助我他的連接池:(我有大約10-20請求mongodb每個網絡請求。(150用戶在線 - 平均)我甚至無法監控統計或連接來自shell的mongodb它給我帶來了異常。

我創建了存儲庫,它根據請求打開並處理連接。 我依賴於以下內容:1)驅動程序有連接池2)經過我的研究(我已經在用戶組中發布了一些關於此的問題) - 我明白創建mongo對象並打開連接不會操作繁重,操作繁重。

但今天我的產量下降了:(可能是我必須保存每個請求的開放連接...

這是指向用戶組的鏈接http://groups.google.com/group/mongodb-user/browse_thread/thread/3d4a4e6c5eb48be3#

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM