本文將逐步解說使用 Azure Cosmos DB Java SDK 的最佳做法。 遵循這些做法,將有助於改善延遲、可用性及提升整體效能。
Checklist
| 已核對 | 主題 | 詳細資料/連結 |
|---|---|---|
| SDK 版本 | 一律使用最新版的 Azure Cosmos DB SDK,以獲得最佳效能。 | |
| 單一用戶端 | 在應用程式的生命周期中使用單一執行個體CosmosClient,以獲得更好的效能。 |
|
| Regions | 請務必盡可能在與 Azure Cosmos DB 帳戶相同的 Azure 區域中執行應用程式,以減少延遲。 啟用 2-4 個區域,並在多個區域中複寫帳戶以獲得最佳可用性。 針對生產工作負載,啟用服務受控容錯移轉。 在沒有此設定的情況下,帳戶將會在寫入區域中斷的所有持續時間內發生寫入可用性遺失的情況,同時由於缺少區域連線能力,手動容錯移轉將不會成功。 若要了解如何使用 Java SDK 來新增多個區域,請造訪這裡 | |
| 可用性與容錯移轉 | 在 SDK 第 4 版中設定 preferredRegions。 在故障轉移期間,寫入操作會傳送至主要寫入區域,而所有讀取操作都會傳送至您首選區域列表中的第一個區域。 如需有關區域容錯移轉機制的詳細資訊,請參閱可用性疑難排解指南。 | |
| CPU | 由於用戶端電腦上的資源不足,您可能會遇到連線能力/可用性問題。 監視執行 Azure Cosmos DB 用戶端之節點的 CPU 使用率,並在使用量很高時擴大/縮小。 | |
| Hosting | 針對生產工作負載最常見的案例,強烈建議盡可能使用至少 4 核心和 8 GB 的記憶體 VM。 | |
| 連線模式 | 使用直接模式以獲得最佳效能。 如需如何進行此作業的指示,請參閱 SDK 第 4 版文件。 | |
| 網路 | 如果使用虛擬機器來執行應用程式,請在 VM 上啟用加速網路,以協助排解因高流量而產生的瓶頸,並減少延遲或 CPU 抖動。 您也可能想要考慮使用高端虛擬機器,其最大 CPU 使用率低於 70%。 | |
| 暫時連接埠耗盡 | 針對疏鬆或偶發連線,我們建議將 idleEndpointTimeout 設定為較高的值。
idleEndpointTimeout 中的 DirectConnectionConfig 屬性可協助控制未使用的連接關閉的時間。 這會減少未使用的連接數目。 根據預設,對端點的閒置連線會保持開啟 1 小時。 如果在閒置端點逾時期間內沒有對特定端點的要求,用戶端將關閉該端點的所有連線,以節省資源和 I/O 成本。 |
|
| 使用適當排程器 (避免竊取事件迴圈 IO Netty 執行緒) | 避免封鎖呼叫:.block() 整個呼叫堆疊都是非同步的,以便從非同步 API 設計模式中獲益並使用適當的執行緒和排程器。 |
|
| 端對端逾時 | 若要取得端對端逾時,請在 Java SDK 中實作端對端逾時原則。 如需有關 Azure Cosmos DB 超時的詳細資訊,請造訪此處 | |
| 重試邏輯 | 暫時性錯誤是一種具有根本原因但即將自行解決的錯誤。 連接到資料庫的應用程式應設計為能夠處理這些暫時性錯誤。 若要處理這些錯誤,請在其程式碼中實作重試邏輯,而不是對使用者呈現為應用程式錯誤。 SDK 有內建的邏輯,可處理這類可重試要求 (例如讀取或查詢作業) 的暫時性失敗。 SDK 不會重試暫時性失敗的寫入,因為寫入不具等冪性。 SDK 可讓使用者設定節流的重試邏輯。 如需有關重試哪些錯誤的詳細資訊,請造訪這裡 | |
| 快取資料庫/集合名稱 | 從設定擷取資料庫和容器名稱,或在啟動時加以快取。 例如 CosmosAsyncDatabase#read() 或 CosmosAsyncContainer#read() 的呼叫會導致對服務的元資料呼叫,這樣的呼叫會消耗系統保留的請求單位 (RU) 限制。 設定資料庫時,應該也只能使用一次 createDatabaseIfNotExists()。 整體來說,這些作業應該不常執行。 |
|
| 平行查詢 | Azure Cosmos DB SDK 支援平行執行查詢,以提升查詢的延遲和輸送量。 建議您將 maxDegreeOfParallelism 中的 CosmosQueryRequestsOptions 屬性設定為您擁有的分割區數目。 如果您不知道分割區數目,請將值設定為 -1,以提供最佳的延遲。 此外,請將 maxBufferedItemCount 設定為預期傳回的結果數目,以限制預先擷取的結果數目。 |
|
| 效能測試輪詢 | 在應用程式上執行測試時,您應該依 RetryAfter 間隔實作退避。 採用輪詢有助於確保您在重試之間花費最少的等待時間。 |
|
| 索引 | Azure Cosmos DB 的編製索引原則也可讓您運用索引路徑 IndexingPolicy#getIncludedPaths() 和 IndexingPolicy#getExcludedPaths(),指定要在編製索引中包含或排除的文件路徑。 確保將未使用的路徑排除於索引編製外,以加快寫入速度。 如需如何使用 SDK 建立索引的範例,請造訪這裡 |
|
| 文件大小 | 指定作業的要求費用會直接與文件大小相互關聯。 建議您減少文件的大小,因為對大型文件的作業成本較對小文件的作業成本更高。 | |
| 頁面大小 | 預設會以 100 個項目或 4 MB 的區塊來傳回查詢結果 (以先達到的限制為準)。 如果查詢將傳回超過 100 個項目,則請增加頁面大小以減少所需的來回行程數目。 隨著頁面大小增加,記憶體耗用量將會增加。 | |
| 啟用查詢計量 | 如需後端查詢執行的其他記錄,請遵循如何使用 Java SDK 擷取 SQL 查詢計量的指示 | |
| SDK 記錄 | 使用 SDK 記錄來擷取額外的診斷資訊,並針對延遲問題進行疑難排解。 記錄 Java SDK 中的 CosmosDiagnostics,以取得服務目前要求的詳細 Azure Cosmos DB 診斷資訊。 作為範例使用案例,如果 CosmosDiagnostics#getDuration() 大於指定的閾值,請在任何例外狀況和已完成的作業上擷取診斷 (例如,如果您的 SLA 為 10 秒,則會在 getDuration()> 10 秒時擷取診斷)。 建議僅在效能測試期間使用這些診斷工具。 如需詳細資訊,請遵循 Java SDK 上的擷取診斷 |
|
| 避免在識別碼中使用任何特殊字元 | 部分字元受到限制,而且無法用於部分屬性:'/'、'\'、'?'、'#'。 一般建議不要在識別碼中使用任何特殊字元,例如資料庫名稱、集合名稱、項目 ID 或分割區索引鍵,以避免發生任何非預期的行為。 |
使用閘道模式時的最佳做法
當您使用網路閘道模式,系統會透過 HTTPS/REST 發出 Azure Cosmos DB 要求。 這些要求受限於每個主機名稱或 IP 位址的預設連線限制。 您可能需要將 maxConnectionPoolSize 調整為較高的值 (100 至 1000),這樣一來用戶端程式庫就可以使用多個同時連至 Azure Cosmos DB 的連線。 在 Java SDK 第 4 版中,GatewayConnectionConfig#maxConnectionPoolSize 的預設值為 1000。 若要變更此值,您可以將 GatewayConnectionConfig#maxConnectionPoolSize 設定為不同的值。
大量寫入工作負載的最佳做法
對於具有大量建立資料負荷的工作負載,請將 CosmosClientBuilder#contentResponseOnWriteEnabled() 請求選項設定為 false。 服務就不會再將已建立或已更新的資源傳回至 SDK。 一般來說,因為應用程式具有正在建立的物件,所以不需要服務來傳回物件。 標頭值仍可存取,例如要求費用。 停用內容回應有助於改善效能,因為 SDK 不再需要配置記憶體或序列化回應主體。 這也可減少網路頻寬使用量,進一步提升效能。
後續步驟
若要深入了解 Java SDK 的效能秘訣,請參閱 Azure Cosmos DB Java SDK 第 4 版的效能秘訣。
若要深入了解如何針對規模和高效能設計您的應用程式,請參閱 Azure Cosmos DB 的資料分割與調整規模。
正在嘗試為遷移至 Azure Cosmos DB 進行容量規劃嗎? 您可以使用現有資料庫叢集的相關資訊進行容量規劃。
- 如果您知道現有資料庫叢集中的虛擬核心和伺服器數目,請參閱使用虛擬核心或 vCPU 來估計要求單位
- 如果您知道目前資料庫工作負載的一般要求率,請參閱使用 Azure Cosmos DB 容量規劃工具來估計要求單位