診斷和疑難排解 Azure Cosmos DB 要求率太大 (429) 例外狀況

適用於:NoSQL

本文包含 NoSQL API 的各種 429 狀態碼錯誤的已知原因和解決方案。 如果您使用適用於 MongoDB 的 API,如需如何針對狀態碼 16500 進行偵錯,請參閱疑難排解適用於 MongoDB 的 API 中的常見問題一文。

「要求速率太大」例外狀況 (也稱為錯誤碼 429),指出您對 Azure Cosmos DB 的要求受到速率限制。

當使用佈建輸送量時,您可設定工作負載所需的輸送量,並以每秒的要求單位 (RU/秒) 進行測量。 針對服務的資料庫作業 (例如讀取、寫入和查詢) 會使用一些要求單位 (RU) 數量。 深入了解要求單位

在指定的秒數中,如果作業耗用超過所佈建的要求單位,Azure Cosmos DB 將傳回 429 例外狀況。 可供使用的要求單位數目會每秒重設。

在採取動作來變更 RU/秒之前,請務必了解速率限制的根本原因,並解決根本問題。

提示

本文中的指引適用於使用佈建輸送量 (自動調整和手動輸送量) 的資料庫和容器。

有不同的錯誤訊息對應至不同類型的 429 例外狀況:

要求速率非常大

這是最常見的案例。 當資料的作業所耗用的要求單位超過佈建的 RU/秒數目時,就會發生此情況。 如果您使用手動輸送量,當您耗用的 RU/秒超過佈建的手動輸送量時,就會發生此類型情況。 如果您使用自動調整,當您耗用的最大 RU/秒超過佈建項目時,就會發生此類型情況。 例如,如果資源佈建的手動輸送量為 400 RU/秒,當您在一秒內耗用的要求單位超過 400 個時,您會看到 429。 如果資源佈建的自動調整最大 RU/秒為 4000 RU/秒 (會在 400 RU/秒 - 4000 RU/秒間調整),當您在一秒內耗用的要求單位超過 4000 個時,您會看到 429 回應。

提示

所有作業都會根據其取用的資源數目進行收費。 這些費用是以要求單位來進行測量。 這些費用包括因 400412449 等這類應用程式錯誤而無法順利完成的要求。查看節流或使用量時,最好調查您的使用量中是否有某個模式已變更,這會導致這些作業增加。 具體來說,檢查標記 412449 (實際衝突)。

如需佈建輸送量的詳細資訊,請參閱 Azure Cosmos DB 中的佈建輸送量

步驟 1:檢查計量以判斷具有 429 錯誤的要求百分比

看到 429 錯誤訊息不一定表示資料庫或容器發生問題。 不論您使用手動或自動調整輸送量,429 回應的百分比很小十分正常,且此現象表示佈建的 RU/秒已最大化。

如何調查

相較於成功要求的整體計數,判斷對您的資料庫或容器要求的哪個百分比導致了 429 回應。 從 Azure Cosmos DB 帳戶中,瀏覽至 [深入解析]> [要求]> [依狀態碼的要求總計]。 篩選至特定的資料庫和容器。

根據預設,Azure Cosmos DB 用戶端 SDK 和資料匯入工具 (例如 Azure Data Factory 和大量執行程式程式庫) 會於 429 時自動重試要求。 此作業通常最多會重試九次。 如此一來,雖然您可能會在計量中看到 429 回應,但這些錯誤甚至可能不會傳回給應用程式。

Total Requests by Status Code chart that shows number of 429 and 2xx requests.

一般來說,針對生產工作負載,如果您在要求 1-5% 之間看見 429,而端對端延遲可供接受,則這是已充分利用 RU/秒的情況良好訊號。 您不需要執行任何動作。 否則,請移至下一個疑難排解步驟。

重要

這個 1-5% 範圍假設您的帳戶分割區平均散發。 如果您的分割區未平均散發,則問題分割區可能會傳回大量 429 錯誤,同時整體速率可能很低。

如果您使用自動調整,即使 RU/秒未調整為最大 RU/秒,您還是可能會在資料庫或容器上看到 429 回應。 如需說明,請參閱使用自動調整但要求速率過大一節。

其中一個常見的問題是「為何在 Azure 監視器計量中看到 429 回應,但在自己的應用程式監視中卻看不到?」如果 Azure 監視器計量顯示您收到 429 回應,但您未在自己的應用程式中看到任何項目,則這是因為 Azure Cosmos DB 用戶端 SDK automatically retried internally on the 429 responses 與要求預設會在後續的重試中成功。 因此並未將 429 狀態碼傳回給應用程式。 在這些情況下,整體的 429 回應速率一般很低,因此可以放心忽略,假設整體的速率介於 1-5% 間,且端對端間的延遲對於應用程式可接受。

步驟 2:判斷是否有經常性存取層分割區

當一個或一些邏輯分割區索引鍵因為較高的要求量而耗用與總計 RU/秒不成比例的數量時,就會發生經常性存取層分割區。 這可能是因為不會平均散發要求的分割區索引鍵設計所導致。 這會導致將許多要求導向至成為「經常性存取層」的一小部分邏輯 (隱含為實體) 分割區。因為邏輯分割區的所有資料都位於一個實體分割區上,而且 RU/秒總計平均散發至實體分割區,所以經常性存取層分割區可能會導致 429 回應,而且輸送量的使用不具效率。

以下是一些會導致經常性存取層分割區的分割策略範例:

  • 您有一個容器會儲存由 date 分割的大量寫入工作負載的 IoT 裝置資料。 單一日期的所有資料都會位於相同的邏輯和實體分割區上。 因為每天寫入的所有資料都有相同的日期,這每天都會產生經常性存取層分割區。
    • 相反地,針對此案例,分割區索引鍵如 id (GUID 或裝置識別碼) 或綜合分割區 (結合 iddate) 會產生較高的值基數,以及更好的要求量分佈。
  • 您有一個多租用戶案例,具有的容器依 tenantId 分割。 如果某個租用戶明顯較其他租用戶更活躍,則會產生經常性存取層分割區。 例如,如果最大的租用戶有 100,000 名使用者,但大部分的租用戶都少於 10 名使用者,則 tenantID 分割時將會有一個經常性存取層分割區。
    • 針對此先前的案例,請考慮將專用容器用於最大租用戶,以更細微的屬性 (例如 UserId) 來分割。

如何識別經常性存取層磁碟分割

若要驗證是否有經常性存取層分割區,請瀏覽至 [深入解析]> [輸送量]> [依 PartitionKeyRangeID 正規化 RU 耗用量 (%)]。 篩選至特定的資料庫和容器。

每個 PartitionKeyRangeId 都會與一個實體分割區對應。 如果某個 PartitionKeyRangeId 明顯高於其他項目的正規化 RU 耗用量 (例如,一個一致處於 100%,但其他處於 30% 或更少),則這可能是經常性存取層分割區的訊號。 深入了解正規化的 RU 耗用計量

Normalized RU Consumption by PartitionKeyRangeId chart with a hot partition.

若要查看哪些邏輯分割區索引鍵耗用最多 RU/秒,請使用 Azure 診斷記錄。 此範例查詢會加總每個邏輯分割區索引鍵上每秒耗用的要求單位總數。

重要

啟用診斷記錄會衍生 Log Analytics 服務的個別費用,這會根據擷取的資料量來計費。 建議您將診斷記錄開啟一段有限的時間以進行偵錯,並在不再需要時關閉。 如需詳細資料,請參閱定價頁面

 CDBPartitionKeyRUConsumption
 | where TimeGenerated >= ago(24hour)
 | where CollectionName == "CollectionName"
 | where isnotempty(PartitionKey)
 // Sum total request units consumed by logical partition key for each second
 | summarize sum(RequestCharge) by PartitionKey, OperationName, bin(TimeGenerated, 1s)
 | order by sum_RequestCharge desc

此範例輸出顯示,在特定的分鐘內,值為 "Contoso" 的邏輯分割區索引鍵會取用約 12,000 RU/秒,而值為 "Fabrikam" 的邏輯分割區索引鍵則使用少於 600 RU/秒。 如果在發生速率限制的期間內,此模式是一致的,這就表示其為經常性存取層分割區。

Logical partition keys consuming the most request units per second.

提示

在任何工作負載中,各邏輯分割區的要求量都會自然變化。 您應判斷經常性存取層分割區是否是因為選擇分割區索引鍵 (其可能需要變更金鑰) 而導致的根本偏態,或是因為工作負載模式中的自然變化而導致的暫時性尖峰。

檢閱如何選擇良好分割區索引鍵的指引。

如果有高百分比的速率限制要求和沒有經常性存取層分割區:

如果有高百分比的速率限制要求,且有基礎經常性存取層分割區:

  • 長期來說,為了獲得最佳成本和效能,請考慮變更分割區索引鍵。 分割區索引鍵無法就地更新,因此需要將資料移轉至具有不同分割區索引鍵的新容器。 Azure Cosmos DB 支援此用途的即時資料移轉工具
  • 短期而言,您可以暫時增加資源整體 RU/秒,以允許更多輸送量通往經常性存取層分割區。 這不是建議的長期策略,因為其會導致過度佈建 RU/秒及更高的成本。
  • 短期而言,您可以使用跨分割區的輸送量轉散發功能 (預覽),將更多 RU/秒指派給經常性存取層的實體分割區。 只有在經常性存取層實體分割區可預測且一致時,才建議這麼做。

提示

增加輸送量時,擴大作業會立即完成,或需要最多 5 到 6 小時才能完成,視您要擴大至的 RU/秒數目而定。 如果要知道可以設定而不會觸發非同步擴大作業 (其需要 Azure Cosmos DB 佈建更多實體分割區) 的最高 RU/秒數目,請將相異 PartitionKeyRangeIds 的數目乘以10,0000 RU/秒。 例如,如果您已佈建 30,000 RU/秒,且有 5 個實體分割區 (每個實體分割區配置 6000 RU/秒),您可以在立即擴大作業中增加至 50,000 RU/秒 (每個實體分割區 10,000 RU/秒)。 增加為 >50,000 RU/秒需要非同步擴大作業。 可在縮放佈建輸送量 (RU/秒) 的最佳做法進行深入了解。

步驟 3:判斷哪些要求正在傳回 429 回應

如何調查具有 429 回應的要求

使用 Azure 診斷記錄來識別哪些要求正在傳回 429 回應以及其所使用的 RU 數目。 此範例查詢會在分鐘層級彙總。

重要

啟用診斷記錄會衍生 Log Analytics 服務的個別費用,這會根據擷取的資料量來計費。 建議您將診斷記錄開啟一段有限的時間以進行偵錯,並在不再需要時關閉。 如需詳細資料,請參閱定價頁面

 CDBDataPlaneRequests
 | where TimeGenerated >= ago(24h)
 | summarize throttledOperations = dcountif(ActivityId, StatusCode == 429), totalOperations = dcount(ActivityId), totalConsumedRUPerMinute = sum(RequestCharge) by DatabaseName, CollectionName, OperationName, RequestResourceType, bin(TimeGenerated, 1min)
 | extend averageRUPerOperation = 1.0 * totalConsumedRUPerMinute / totalOperations
 | extend fractionOf429s = 1.0 * throttledOperations / totalOperations
 | order by fractionOf429s desc

例如,此範例輸出顯示每分鐘有 30% 的建立文件要求都受到速率限制,每個要求耗用平均 17 個 RU。 Requests with 429 in Diagnostic Logs.

使用 Azure Cosmos DB 容量規劃工具

您可使用 Azure Cosmos DB 容量規劃工具,來了解根據您的工作負載 (作業數量和類型以及文件大小) 的最佳佈建輸送量。 您可以藉由提供樣本資料來進一步自訂計算,以取得更精確的估計。

建立、取代或 upsert 文件要求時的 429 回應
  • 根據預設,在 NoSQL API 中,預設會編製所有屬性的索引。 調整索引原則,以只為所需的屬性編製索引。 這會降低每個「建立文件」作業所需的要求單位,這會降低查看 429 回應的可能性,或讓您針對相同數量的已佈建 RU/秒達到更高的作業數。
查詢文件要求的 429 回應
執行預存程序時的 429 回應
  • 預存程序適用於需要跨分割區索引鍵值寫入交易的作業。 不建議使用預存程序進行大量的讀取或查詢作業。 為了達到最佳效能,您應該在用戶端上使用 Azure Cosmos DB SDK 來完成這些讀取或查詢作業。

自動調整的要求速率過大

本文中的所有指引均同時適用於手動和自動調整輸送量。

使用自動調整時,常見的問題為:「使用自動調整時是否仍會顯示 429 回應呢?」

是。 有下列兩種主要案例會發生此問題。

案例 1:當整體耗用的 RU/秒超過資料庫或容器的最大 RU/秒時,服務將會視情況節流要求。 這類似於超出資料庫或容器的整體手動佈建輸送量。

情節 2:如果有經常性分割區 (亦即,邏輯分割區索引鍵值與其他分割區索引鍵值相比之下,要求量較高),則基礎實體分割區可能超過其 RU/秒的預算。 最佳做法是避免常用分割區,選擇良好的分割區索引鍵,讓儲存體和輸送量能夠平均分佈。 這類似於使用手動輸送量時存在經常性分割區。

例如,如果您選取 20,000 RU/秒最大輸送量選項,並且有 200 GB 的儲存體,四個實體分割區,則每個實體分割區最多可自動調整至 5000 RU/秒。 如果特定邏輯分割區索引鍵上有經常性分割區,當其所在的基礎實體分割區超過 5000 RU/秒時 (亦即超過 100% 的標準化使用率),就會看到 429 回應。

遵循步驟 1步驟 2步驟 3 中的指引來針對上述情況進行偵錯。

另一個常見的問題是,為什麼標準化 RU 耗用量為 100%,但自動調整未調整為最大 RU/秒?

這通常發生在暫時性或間歇性使用量尖峰的工作負載。 當您使用自動調整時,Azure Cosmos DB 只會在標準化 RU 使用量為 100% 時,以 5 秒間隔的持續期間將 RU/秒調整為最大輸送量。 這麼做可確保調整邏輯對使用者而言具有成本效益,因為可確保單一且暫時的尖峰不會導致不必要的調整和較高的成本。 發生暫時尖峰時,系統通常會擴大至高於先前調整為 RU/秒的值,但低於最大 RU/秒。 深入了解如何使用自動調整來解讀標準化 RU 耗用量計量

中繼資料要求的速率限制

在資料庫和/或容器上執行大量的中繼資料作業時,可能會發生中繼資料速率限制。 中繼資料作業包括:

  • 建立、讀取、更新或刪除容器或資料庫
  • 列出 Azure Cosmos DB 帳戶中的資料庫或容器
  • 查詢供應項目以查看目前佈建的輸送量

這些作業有系統保留的 RU 限制,因此增加資料庫或容器佈建的 RU/秒不會有任何影響,因此不建議使用。 請參閱控制平面服務限制

如何調查

瀏覽至 [Insights]> [系統]> [依狀態碼的中繼資料要求]。 篩選至特定的資料庫和容器 (如需要)。

Metadata requests by status code chart in Insights.

  • 如果您的應用程式需要執行中繼資料作業,請考慮實作輪詢原則,以較低的速率傳送這些要求。

  • 使用靜態 Azure Cosmos DB 用戶端執行個體。 當 DocumentClient 或 CosmosClient 初始化時,Azure Cosmos DB SDK 會擷取關於帳戶的中繼資料,包括一致性層級、資料庫、容器、分割區和供應項目的相關資訊。 此初始化可能會耗用大量 RU,因此無法太常執行。 使用單一 DocumentClient 執行個體,並在應用程式的存留期中使用。

  • 快取資料庫和容器的名稱。 從設定擷取資料庫和容器的名稱,或在啟動時加以快取。 ReadDatabaseAsync/ReadDocumentCollectionAsync 或 CreateDatabaseQuery/CreateDocumentCollectionQuery 之類的呼叫將會產生對服務的中繼資料呼叫,這會從系統保留的 RU 限制取用。 這些作業應該不常執行。

由於暫時性服務錯誤的速率限制

此 429 錯誤是在要求發生暫時性服務錯誤時傳回。 增加資料庫或容器的 RU/秒將不會有任何影響,因此不建議這麼做。

重試要求。 如果錯誤持續數分鐘,請從 Azure 入口網站提出支援票證。

下一步