MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Szybkość żądań CosmosDb jest duża z insertMany

Sterownik Mongo informuje, które rekordy zawierają błędy, a które w ogóle nie zostały przetworzone. Jeśli wszystkie błędy (zazwyczaj jeden) mają kod 16500, oznacza to, że problem polega na dławieniu i ponawianiu błędów, a pozostałe rekordy są bezpieczne. W przeciwnym razie Twoje błędy są spowodowane przez coś innego i powinieneś przeprowadzić analizę i zdecydować, czy kontynuować ponowną próbę.

Sterownik Mongo nie zwraca nagłówka HTTP, w którym Cosmos DB sugeruje opóźnienie przed ponowną próbą, ale to nie jest wielka sprawa. Opóźnienie i tak nie gwarantuje sukcesu, ponieważ inne żądania trafiające do tej samej bazy danych mogą zużywać RU. Lepiej jest poeksperymentować i ustalić własne zasady ponawiania prób. Poniżej znajduje się proste, rekurencyjne rozwiązanie, które kontynuuje ponawianie prób, aż wszystko będzie w porządku lub zostanie osiągnięty limit ponownych prób.

    private async Task InsertManyWithRetry(IMongoCollection<BsonDocument> collection, 
        IEnumerable<BsonDocument> batch, int retries = 10, int delay = 300)
    {
        var batchArray = batch.ToArray();

        try
        {
            await collection.InsertManyAsync(batchArray);
        }
        catch (MongoBulkWriteException<BsonDocument> e)
        {
            if (retries <= 0)
                throw;

            //Check if there were any errors other than throttling.
            var realErrors = e.WriteErrors.Where(we => we.Code != 16500).ToArray();
            //Re-throw original exception for now.
            //TODO: We can make it more sophisticated by continuing with unprocessed records and collecting all errors from all retries.
            if (realErrors.Any())
                throw;

            //Take all records that had errors.
            var errors = e.WriteErrors.Select(we => batchArray[we.Index]);
            //Take all unprocessed records.
            var unprocessed = e.UnprocessedRequests
                .Where(ur => ur.ModelType == WriteModelType.InsertOne)
                .OfType<InsertOneModel<BsonDocument>>() 
                .Select(ur => ur.Document);

            var retryBatchArray = errors.Union(unprocessed).ToArray();

            _logger($"Retry {retryBatchArray.Length} records after {delay} ms");

            await Task.Delay(delay);

            await InsertManyWithRetry(collection, retryBatchArray, retries - 1, delay);
        }
    }


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Usuwanie pliku database.yml podczas używania Mongoid w Rails 3.2

  2. BSON::ObjectId vs Mongo::ObjectID

  3. Patch REST API do częściowej aktualizacji MongoDB w .NET

  4. MongoDB atomowe findOrCreate:findOne, wstaw, jeśli nie istnieje, ale nie aktualizuj

  5. Błąd podczas instalacji mongodb na Ubuntu 16.04