Лучшие практики.NET для соединений MongoDB?

Я играл с MongoDB недавно (Это - УДИВИТЕЛЬНО FAST), использование драйвера C# на GitHub. Все работает просто великолепно в моем небольшом единственном потоковом консольном приложении, с которым я тестирую. Я могу добавить, что 1 000 000 документов (да, миллион) за менее чем 8 секунд, работая единственный распараллелили. Я только получаю эту производительность, если я использую соединение вне объема для цикла. Другими словами, я сохраняю соединение открытым для каждого, вставляют вместо того, чтобы соединиться для каждого, вставляют. Очевидно, это изобретено.

Я думал, что проверну его на ступеньку выше, чтобы видеть, как это работает с несколькими потоками. Я делаю это, потому что я должен моделировать веб-сайт с несколькими параллельными запросами. Я вращаюсь между 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);
        }
    }
}
60
задан shA.t 21 December 2016 в 14:22
поделиться

3 ответа

Что нужно помнить о статическом соединении, так это то, что оно используется всеми вашими потоками. Вам нужно одно соединение на поток.

9
ответ дан 24 November 2019 в 17:45
поделиться

Несколько, но все же представляет интерес CSMongo, драйвер C# для MongoDB, созданный разработчиком jLinq. Вот пример:

//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
ответ дан 24 November 2019 в 17:45
поделиться

Пул подключений должен быть вашим ответом.

Функция находится в стадии разработки (подробнее см. http://jira.mongodb.org/browse/CSHARP-9 ).

Прямо сейчас для веб-приложения лучше всего подключиться по BeginRequest и освободить соединение по EndRequest. Но мне кажется, что операция обходится слишком дорого для каждого запроса без пула соединений. Поэтому я решил создать глобальный объект Mongo и использовать его в качестве общего ресурса для всех потоков (если вы прямо сейчас получите последнюю версию драйвера C # из github, они также немного улучшат производительность для параллелизма).

Я не знаю недостатков использования объекта Global Mongo. Так что подождем, пока это прокомментирует другой эксперт.

Но я думаю, что смогу жить с этим, пока функция (пул соединений) не будет завершена.

0
ответ дан 24 November 2019 в 17:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: