簡體   English   中英

MongoDB BulkWrite ExceededTimeLimit 錯誤 in.Net

[英]MongoDB BulkWrite ExceededTimeLimit error in .Net

我正在嘗試使用 c# 驅動程序(v2.11.6)上的 BulkWrite 將大約 150k 更新推送到 Mongo 數據庫(在 Windows 上運行的 v 4.2.9,具有兩個節點的階段副本),看起來這是不可能的。 該項目是.Net Framework 4.7.2。

Mongo c# 驅動程序文檔很糟糕,但不知何故,在論壇上並通過大量谷歌搜索,我終於找到了一種如何使用批處理運行大約 150k 更新的方法,就像這樣(對於 SO 稍微簡化了一點):

client = new MongoClient(connString);
database = client.GetDatabase(db);

// Build all the updates
List<UpdateOneModel<GroupEntry>> updates = new List<UpdateOneModel<GroupEntry>>();
foreach (GroupEntry groupEntry in stats)
{
  FilterDefinition<GroupEntry> filter = Builders<GroupEntry>.Filter.Eq(e => e.Key, groupEntry.Key);

  UpdateDefinitionBuilder<GroupEntry> update = Builders<GroupEntry>.Update;
  var groupEntrySubUpdates = new List<UpdateDefinition<GroupEntry>>();

  if (groupEntry.Value.Clicks != 0)
    groupEntrySubUpdates.Add(update.Inc(u => u.Value.Clicks, groupEntry.Value.Clicks));

  if (groupEntry.Value.Position != 0)
    groupEntrySubUpdates.Add(update.Set(u => u.Value.Position, groupEntry.Value.Position));

  UpdateOneModel<GroupEntry> groupEntryUpdate = new UpdateOneModel<GroupEntry>(filter, update.Combine(updates));
  groupEntryUpdate.IsUpsert = true;

  updates.Add(groupEntryUpdate);
}

// Now BulkWrite them in transaction to make sure data are consistent
IClientSessionHandle session = client.StartSession();
session.StartTransaction();

IMongoCollection<GroupEntry> collection = database.GetCollection<GroupEntry>(collectionName);

// Following line FAILS after some time
BulkWriteResult<GroupEntry> bulkWriteResult = collection.BulkWrite(session, updates);

if (!bulkWriteResult.IsAcknowledged)
  throw new Exception("Mongo BulkWrite is not acknowledged!");

session.CommitTransaction();

問題是我不斷收到以下異常:

{
   "operationTime":Timestamp(1612737199,
   1),
   "ok":0.0,
   "errmsg":"Exec error resulting in state FAILURE :: caused by :: operation was interrupted",
   "code":262,
   "codeName":"ExceededTimeLimit",
   "$clusterTime":{
      "clusterTime":Timestamp(1612737199,
      1),
      "signature":{
         "hash":new BinData(0,
         "ljcwS5Gf2JBpEu/OgPFbvRqclLw="")",
         "keyId":"NumberLong(""6890288652832735234"")"
      }
   }
}

有沒有人有任何線索? Mongo c# 驅動程序文檔完全沒用。 看起來我應該以某種方式設置屬性$maxTimeMS ,但在 BulkInsert 上是不可能的。 我努力了:

  • 重新啟動和重建
  • 不同版本的 MongoDriver
  • 為 MongoClient 和 session 上的所有“超時”屬性設置更大的超時
  • 為 BulkWrite 創建更小的批次(每批次最多 1000 個項目)。 50-100 次更新后失敗。
  • 在無用的 Mongo docs 和 Mongo JIRA 上花費數小時

到目前為止還沒有運氣。 有趣的是,同樣的方法適用於 c# 驅動程序 2.10.3 on.Net CORE 3.1(是的,我試過),即使批量更大(大約 300k 更新)。

我錯過了什么?

編輯:

我嘗試根據 dododo 的評論將 maxCommitTime 設置為 25 分鍾,如下所示:

IClientSessionHandle session = client.StartSession(new ClientSessionOptions()
{
  DefaultTransactionOptions = new TransactionOptions(new Optional<ReadConcern>(ReadConcern.Default), 
    new Optional<ReadPreference>(ReadPreference.Primary), 
    new Optional<WriteConcern>(WriteConcern.Acknowledged), 
    new Optional<TimeSpan?>(TimeSpan.FromMinutes(25)))
});

它現在在執行提交時拋出異常: NoSuchTransaction - 事務 1 已中止。 . 我們檢查了 MongoDB 日志文件,並在其中發現了新的錯誤:

在 session 09ea7755-7148-43e8-83d8-8bf58c211bda 上使用 txnNumber 1 中止事務,因為它的運行時間超過了 'transactionLifetimeLimitSeconds

根據docs ,默認為 60 秒。 所以我們將它設置為 5 分鍾,現在它可以工作了。

所以,謝謝你 dododo 為我指明了正確的方向。

無論如何,如果 Mongo 團隊能更好地描述錯誤並在基本 CRUD 操作之上編寫文檔,那就太好了。

正如 dododo 所建議的,這個錯誤是服務器關閉事務的表現,因為它比transactionLifetimeLimitSeconds花費的時間更長,默認為 60 秒。 所以需要做兩件事:

  1. 將參數transactionLifetimeLimitSeconds設置為 60 秒以上
  2. maxCommitTime設置為更高的值。 我找不到默認值,所以我將其設置為 10 分鍾(與 transactionLifetimeLimitSeconds 相同)。 在啟動 session 時設置它(參見問題)。

無論如何,這方面的文檔都丟失了,並且錯誤本身具有誤導性。 所以我希望它能幫助任何必須處理這個問題的人。

暫無
暫無

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

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