使用 Azure Cosmos DB SDK 設計復原應用程式
適用於:NoSQL
製作透過任何 SDK 與 Azure Cosmos DB 互動的用戶端應用程式時,請務必了解幾個重要的基本概念。 本文是一個設計指南,可協助您了解這些基本概念,並設計復原性應用程式。
概觀
如需本文所討論概念的概觀影片,請參閱:
連線模式
Azure Cosmos DB SDK 可以用兩種連線模式中連線至服務。 .NET 和 JAVA SDK 可以在閘道和直接模式中連線到服務,而其他 SDK 則只能在閘道模式中連線。 閘道模式使用 HTTP 通訊協定,而直接模式一般會使用 TCP 通訊協定。
無論 SDK 設定使用哪個模式,擷取中繼資料 (例如帳戶、容器和路由資訊) 時一律會採用閘道模式。 此資訊會快取至記憶體中,並用來連線到服務複本。
總而言之,閘道模式中的 SDK 可預期為 HTTP 流量,而對於直接模式的 SDK,在不同的情況下 (例如初始化或擷取中繼資料,或路由資訊) 可預期為 HTTP 和 TCP 流量的組合。
用戶端執行個體和連線
無論連線模式為何,在每個應用程式的每個帳戶 SDK 用戶端保持單一執行個體非常重要。 HTTP 和 TCP 的連線範圍都限於用戶端執行個體。 大部分的計算環境對於可同時開啟的連線數目都有限制,且達到這些限制時,連線將會受到影響。
分散式應用程式和網路
當您設計分散式應用程式時,包含三個主要元件:
- 您的應用程式及其執行環境。
- 網路,包含應用程式與 Azure Cosmos DB 服務端點之間的任何元件。
- Azure Cosmos DB 服務端點。
發生失敗時,原因通常來自這三個區域之一,而且請務必了解,由於系統的分散式本質,因此無法預期這些元件有 100% 的可用性。
Azure Cosmos DB 有一組完整的可用性 SLA,但其中沒有任何一個 SLA 的可用性為 100%。 將應用程式連線到服務端點的網路元件可能會發生暫時性硬體問題,並遺失封包。 即使是應用程式執行所在的計算環境,也可能出現影響作業的 CPU 尖峰。 這些失敗狀況可能會影響 SDK 的作業,並通常顯示為特定程式碼的錯誤。
透過對 SDK 所提供的回應實作重試原則,您的應用程式應可從這些元件中特定程度的潛在失敗中復原。
我的應用程式應該針對錯誤重試嗎?
簡短的答案為應該。 但並非所有錯誤都適合重試,某些錯誤或狀態碼並非暫時性問題。 下表詳細說明這些錯誤:
狀態碼 | 應該新增重試 | SDK 重試 | 描述 |
---|---|---|---|
400 | No | No | 不正確的要求 |
401 | No | No | 未獲授權 |
403 | 選擇性 | No | 禁止 |
404 | No | No | 找不到資源 |
408 | Yes | Yes | 要求逾時 |
409 | No | No | 衝突失敗是指當為資源寫入作業提供的身分識別 (識別碼和分割區索引鍵) 由現有資源所採用,或違反唯一索引鍵條件限制的情況。 |
410 | Yes | Yes | 消失例外狀況 (不違反 SLA 的暫時性失敗) |
412 | No | No | 先決條件失敗,即此作業指定了不同於伺服器上可用版本的 eTag。 這屬於開放式同步存取錯誤。 讀取最新版的資源及更新要求上的 eTag 之後,重試要求。 |
413 | No | No | 要求實體太大 |
429 | Yes | Yes | 針對 429 可放心執行重試。 請參閱指南以針對 HTTP 429 進行疑難排解。 |
449 | Yes | Yes | 這是只有寫入作業才會發生的暫時性錯誤,可放心執行重試。 這可能代表有設計上的問題,導致過多並行作業嘗試更新 Azure Cosmos DB 中的相同物件。 |
500 | No | No | 發生預期外的伺服器錯誤而導致作業失敗。 請提出 Azure 支援問題來連絡支援人員。 |
503 | Yes | Yes | 服務無法使用 |
在上表中,第二個資料行上標示為 [是] 的所有狀態碼,都應該考慮在應用程式中進行重試。
HTTP 403
一般而言,Azure Cosmos DB SDK 不會在 HTTP 403 失敗時重試,但您的應用程式可能會決定針某些與 HTTP 403 相關聯的特定錯誤進行重試。 例如,如果您收到指出分割區索引鍵已滿的錯誤,您可能會決定根據某些商務規則來變更您嘗試寫入文件的分割區索引鍵。
HTTP 429
根據預設,Azure Cosmos DB SDK 會針對 HTTP 429 錯誤進行重試,方法是等候指定的時間和重試之後,遵循用戶端設定並接受服務的回應 x-ms-retry-after-ms
標頭。
當超過 SDK 重試時間上限時,錯誤會傳回至您的應用程式。 在理想情況下,檢查回應中的 x-ms-retry-after-ms
標頭可作為提示,以決定重試要求之前等待的時間長度。 另一個替代方法是指數輪詢演算法,或設定用戶端針對 HTTP 429 延長重試。
HTTP 449
Azure Cosmos DB SDK 會遇到 HTTP 449 時重試,並在固定時間內進行累加輪詢,以容納大部分的案例。
當超過自動 SDK 重試時間上限時,錯誤會傳回至您的應用程式。 HTTP 449 錯誤可以安全地重試。 由於寫入作業具有高度並行性質,因此最好採用隨機輪詢演算法,以避免在固定間隔之後重複相同模式的並行。
逾時和連線相關失敗 (HTTP 408/503)
網路逾時和連線失敗是最常見的錯誤之一。 Azure Cosmos DB SDK 本身具有復原性,如果重試可行,則會在 HTTP 和 TCP 通訊協定上針對逾時和連線問題進行重試:
- 針對讀取作業,SDK 會重試任何逾時或連線相關錯誤。
- 針對寫入作業,SDK 不會重試,因為這些作業不會產生相同結果。 如果等候回應時發生逾時,則無法知道要求是否已到達服務。
如果帳戶有多個區域可用,SDK 也會嘗試跨區域重試。
由於逾時和連線失敗的特性,這些錯誤可能不會出現在您的帳戶計量中,因為計量只包含服務端發生的失敗。
建議應用程式針對這些案例設定專屬的重試原則,並考慮如何解決寫入逾時。 例如,如果前一個要求確實已到達服務,則針對「建立逾時」重試可能會產生 HTTP 409 (衝突),但如果沒有到達,則要求將成功。
語言特定的實作詳細資料
如需語言的進一步實作詳細資料,請參閱:
重試是否會影響延遲?
從用戶端的觀點來看,任何重試都會影響作業的端對端延遲。 當應用程式 P99 延遲受到影響時,了解目前的重試以及這些問題的解決方法很重要。
Azure Cosmos DB SDK 會在其記錄和診斷中提供詳細資訊,以協助識別正在進行哪些重試。 如需詳細資訊,請參閱如何收集 .NET SDK 診斷,以及如何收集 JAVA SDK 診斷。
如何減輕重試延遲?
根據情況,在大部分情況下,SDK 會將要求路由傳送至本機區域、寫入區域 (在單一區域寫入案例中),或慣用區域清單中的第一個區域。 此優先順序主要會連線到最接近或最理想的資料中心,將狀況良好案例中的延遲降到最低。
不過,此優先順序也表示,針對特定錯誤案例,一律會先在一個特定區域中嘗試導致失敗的要求。 如果該案例中偏好容錯移轉至另一個區域,這通常就會在基礎結構 (流量管理員) 層處理,而不是在 SDK 層級處理。 基礎結構的適當設定和組態可確保在區域性中斷期間有效率地重新路由傳送流量,藉此減輕中斷案例中跨區域重試的延遲。 如需設定基礎結構層級容錯移轉的詳細資訊,請參閱 Azure 流量管理員文件。 某些 SDK 支援直接在 SDK 層級實作類似的容錯移轉策略。 例如,請參閱 Java SDK 的高可用性。
如果是區域中斷呢?
Azure Cosmos DB SDK 具備區域可用性,並可在另一個帳戶區域上執行重試。 請參閱多區域環境重試案例和設定一文,以了解哪些案例涉及其他區域。
何時應連絡客戶支援
在連絡客戶支援之前,請先執行下列步驟:
- 相較於作業成功時,目前所影響的作業量為何? 受影響作業是否在服務 SLA 內?
- P99 延遲是否受到影響?
- 失敗是否與我的應用程式應重試的錯誤碼相關,且應用程式是否涵蓋此類重試?
- 失敗會影響所有應用程式執行個體還是只會影響子集? 當問題縮減為執行個體的子集時,通常是與這些執行個體相關的問題。
- 您是否已閱讀上表中的相關疑難排解文件,排除掉應用程式環境的問題?
如果所有應用程式執行個體都受到影響,或受影響的作業百分比在服務 SLA 之外,或影響您自己的應用程式 SLA 和 P99,請連絡客戶支援。
下一步
- 了解多區域環境重試案例和設定
- 檢閱可用性 SLA
- 使用最新版 .NET SDK
- 使用最新版 JAVA SDK
- 使用最新版 Python SDK
- 使用最新版 Node SDK