Многопоточное C# приложение - MongoDB пропускает записи во время вставки без ошибок - PullRequest
1 голос
/ 13 марта 2020

Я работаю над Mon go Db C# Версия драйвера 2.0.1.27 и Mon go Db версия 3.0.

Наша цель - вставить огромное количество документов в коллекцию MongoDb, используя Метод «Insert».

Наша архитектура вызывает этот метод Add несколько раз для каждого потока. Ниже приведен метод Add:

public bool Add(CallContext context, FileQueueEntity entity)
        {
            bool bResult = false;
            // This logic is to prevent duplicate file.
            // Consider new algorithm if supporting other files types
            bResult = Delete(context, entity);
            if (context.ErrorList.Count == 0)
            {
                var server = GetMongoServer();
                try
                {
                    var database = GetMongoDatabase(server);
                    var collection = database.GetCollection<FileQueueEntity>("QueueCollection");

                    entity.BaseMeta = null;
                    entity.IsNew = false;
                    collection.Insert(entity);
                    context.AddToUpdatedList(entity);
                }
                catch (Exception ex)
                {
                    bResult = false;
                    context.AddError(ErrorSeverity.System, "DataAccess.AddFileQueue", GetThreadExceptionMessage(ex));
                }
                finally
                {
                }
            }
            return bResult;
        }

Ниже приведен метод Get MongoDatabase:

private MongoDatabase GetMongoDatabase(MongoServer mongoServer)
        {
            return mongoServer.GetDatabase(mConnectionBuilder.InitialCatalog);
        }

Ниже приведен метод GetMongoServer

private MongoServer GetMongoServer()
        {
            System.Threading.Monitor.Enter(_lock);
            try
            {
                if (_mongoServer != null)
                {
                    return _mongoServer;
                }

                DatabaseProviderFactory factory = new DatabaseProviderFactory();
                var aDatabase = factory.Create("ConnectionStringName");
                mConnectionBuilder = new SqlConnectionStringBuilder(aDatabase.ConnectionString);
                var credential = MongoCredential.CreateCredential(mConnectionBuilder.InitialCatalog, mConnectionBuilder.UserID, mConnectionBuilder.Password);
                MongoServerSettings databaseSettings = new MongoServerSettings();

                var connectionStrings = mConnectionBuilder.DataSource.Split(',');

                if (connectionStrings != null && connectionStrings.Count() > 1)
                {
                    string ipAddress = connectionStrings[0];
                    int portNumber = Convert.ToInt32(connectionStrings[1], CultureInfo.InvariantCulture);
                    databaseSettings.Credentials = new[] { credential };
                    databaseSettings.Server = new MongoServerAddress(ipAddress, portNumber);
                }

                _mongoServer = new MongoServer(databaseSettings);
                return _mongoServer;
            }
            finally
            {
                System.Threading.Monitor.Exit(_lock);
            }

        }

, и он называется таким образом:

foreach (var n in entities)
{
    Add(n);
}

Foreach l oop вызывается для каждого экземпляра отдельно.

Проблема в том, что мы видим, что все файлы не достигают БД, как каждый Время от времени в таблице отсутствуют случайные файлы.

Сущность, которую мы отправляем, очень легкая (едва ли 400-500 байт). Количество файлов будет не более 2000-5000, которые будут очищаться ежедневно. Таким образом, максимальный объем памяти в этом случае не будет превышен

Например:

Thread 1: 50 files  -   Random 48 files are inserted
Thread 2: 80 files  -   Random 75 files are inserted
Thread 3: 70 files  -   Random 60 files are inserted
Thread 4: 60 files  -   Random 59 files are inserted

Отсутствует ли какая-либо конфигурация Mon go, так как она не выдает никаких исключений и не может молча вставить записи, что немного странно.

Ответ, который мы получаем при вставке:

Response: { "ok" : 1, "n" : NumberLong(0) }

Замечено, что все случайные файлы из каждого потока каждый раз терпят неудачу .

Может ли кто-нибудь помочь мне в этом? Нам не хватает какой-либо конфигурации MongoDB?

1 Ответ

0 голосов
/ 13 марта 2020

пара точек для рассмотрения:

  1. IMongoColleciton можно получить один раз и сохранить как статический / одиночный. это рекомендуемый шаблон .

  2. удаление избыточно. используйте collection.ReplaceOne(e => e.Id == entity.Id, entity);

  3. еще лучше, используйте массовое замещение с пакетами от 50 до 100 объектов в каждой итерации или потоке.

  4. попробуйте обновить до последней версии сервера и драйвера. Так много хороших изменений произошло с версии 2.0

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...