這很重要
這「不是」適用於 Azure Cosmos DB 的最新 Java SDK! 你應該先升級專案到 Azure Cosmos DB Java SDK v4 ,然後閱讀 Azure Cosmos DB Java SDK v4 效能提示指南。 請依照 Migrate to Azure Cosmos DB Java SDK v4 指南和 Reactor 與 RxJava 指南中的指示升級。
這些效能提示僅適用於 Azure Cosmos DB Sync Java SDK v2。 請參考 Maven 資料庫 以獲取更多資訊。
這很重要
2024 年 2 月 29 日,Azure Cosmos DB Sync Java SDK v2.x 將正式退役;SDK 及所有使用 SDK 的應用程式 都將持續運作;Azure Cosmos DB 將停止為此 SDK 提供進一步的維護與支援。 建議您依照上述指示遷移至 Azure Cosmos DB Java SDK v4。
Azure Cosmos DB 是一個既快速又彈性的分散式資料庫,可在獲得延遲與輸送量保證的情況下順暢地調整。 使用 Azure Cosmos DB 時,您不須進行主要的架構變更,或是撰寫複雜的程式碼來調整您的資料庫。 相應增加和減少就像進行單一 API 呼叫一樣簡單。 欲了解更多,請參閱 如何配置容器吞吐量 或 如何配置資料庫吞吐量。 不過,由於 Azure Cosmos DB 是透過網路呼叫存取,用戶端可以做一些優化,讓使用 Azure Cosmos DB Sync Java SDK v2 達到最高效能。
因此,如果您是問:「如何改善資料庫效能?」,請考慮下列選項:
網路
連線模式:使用 DirectHttps
客戶端如何連接 Azure Cosmos DB 對效能有重要影響,尤其是在觀察到的客戶端延遲方面。 有一個關鍵的設定可用於設定用戶端 ConnectionPolicy —— ConnectionMode。 兩種可用的連接模式為:
-
閘道模式在所有 SDK 平台上都支援,且是預設的預設模式。 如果你的應用程式運行在有嚴格防火牆限制的企業網路中,Gateway 是最佳選擇,因為它使用標準 HTTPS 埠和單一端點。 然而,效能的取捨在於閘道模式每次向 Azure Cosmos 資料庫讀取或寫入資料時,都會額外跳躍一次網路。 因此,DirectHttps 模式因網路跳數較少而提供較佳的效能。
Azure Cosmos DB Sync Java SDK v2 使用 HTTPS 作為傳輸協定。 HTTPS 使用 TLS 進行初始認證與加密流量。 使用 Azure Cosmos DB Sync Java SDK v2 時,只需開啟 HTTPS 443 埠。
ConnectionMode 會在建構 DocumentClient 實例時以 ConnectionPolicy 參數設定。
Sync Java SDK V2 (Maven com.microsoft.azure::azure-documentdb)
public ConnectionPolicy getConnectionPolicy() { ConnectionPolicy policy = new ConnectionPolicy(); policy.setConnectionMode(ConnectionMode.DirectHttps); policy.setMaxPoolSize(1000); return policy; } ConnectionPolicy connectionPolicy = new ConnectionPolicy(); DocumentClient client = new DocumentClient(HOST, MASTER_KEY, connectionPolicy, null);
為了效能在相同 Azure 區域中共置用戶端
可能的話,請將任何呼叫 Azure Cosmos DB 的應用程式放在與 Azure Cosmos DB 資料庫相同的區域中。 以約略的比較來說,在相同區域內對 Azure Cosmos DB 進行的呼叫會在 1-2 毫秒內完成,但美國西岸和美國東岸之間的延遲則會 >50 毫秒。 要求的延遲可能會有所不同,這取決於每次要求從用戶端傳送到 Azure 資料中心邊界時所採用的路由。 確保呼叫端應用程式與佈建的 Azure Cosmos DB 端點位於相同的 Azure 區域中,將可能達到最低的延遲。 如需可用區域的清單,請參閱 Azure 區域。
SDK 使用
安裝最新的 SDK
Azure Cosmos DB SDK 會持續改善以提供最佳效能。 若要判斷最新的 SDK 改進功能,請造訪 Azure Cosmos DB SDK。
在應用程式存留期內使用單一 Azure Cosmos DB 用戶端
每個 DocumentClient 實例皆為執行緒安全,並在直接模式下執行高效的連線管理與位址快取。 為了讓 DocumentClient 能更有效率地管理連線並提升效能,建議在應用程式的整個生命週期內,每個 AppDomain 使用單一 DocumentClient 實例。
使用閘道模式時,增加每台主機的 MaxPoolSize
Azure Cosmos DB 資料庫的請求在使用 Gateway 模式時是透過 HTTPS/REST 發出,並受限於每個主機名稱或 IP 地址的預設連接限制。 你可能需要將 MaxPoolSize 設定得更高(200-1000),讓用戶端函式庫能同時利用多個連接 Azure Cosmos DB。 在 Azure Cosmos DB Sync Java SDK v2 中, ConnectionPolicy.getMaxPoolSize 的預設值是 100。 使用 setMaxPoolSize 來更改這個值。
調整分割集合的並行查詢
Azure Cosmos DB Sync Java SDK 版本 1.9.0 及以上支援平行查詢,讓你能平行查詢分割後的集合。 欲了解更多資訊,請參閱與 SDK 相關的 程式碼範例 。 平行查詢的設計目的是相較於序列查詢,提升查詢延遲與吞吐量。
(a) 調整 setMaxDegreeOfParallelism: 平行查詢透過平行查詢多個分割區來運作。 然而,來自單一分割集合的資料會依查詢順序序列擷取。 因此,使用 setMaxDegreeOfParallelism 來設定分割區的數量,以在所有其他系統條件保持不變的情況下,最大化達成性能最佳化查詢的可能性。 如果你不知道分割的數量,可以使用 setMaxDegreeOfParallelism 設定一個較高的數值,系統會選擇最小值(分割數量、使用者輸入)作為最大平行度數。
值得注意的是,若資料在所有分區之間相對於查詢分布均勻,平行查詢執行能產生最大效益。 如果分割後的集合被分割成查詢回傳的所有或大部分資料集中在幾個分割區(最壞情況下只有一個分割區),那麼查詢的效能將會被這些分割區限制。
(b) 調整 setMaxBufferedItemCount: 平行查詢設計用於在用戶端處理目前批次結果時預先取得結果。 預先擷取有助於改善查詢的整體延遲。 setMaxBufferedItemCount 限制預先取得的結果數量。 透過將 setMaxBufferedItemCount 設定為預期回傳的結果數(或更高數字),使查詢能從預取中獲得最大效益。
預取的運作方式與 MaxDegreeOfParallelism 無關,且所有分割區的資料皆有一個緩衝區。
在 getRetryAfterInMilliseconds 間隔時實作 backoff
在效能測試期間,你應該增加負載,直到有少量請求受到限制為止。 若被限速,用戶端應用程式應在伺服器指定的重試間隔內逐步減速。 確保遵循回退機制可以使您在重試之間等待的時間最少。 重試政策支援包含在 Azure Cosmos DB Sync Java SDK 版本 1.8.0 及以上。 欲了解更多資訊,請參閱 getRetryAfterInMilliseconds。
擴增用戶端工作負載
如果你在高吞吐量的水平(>50,000 RU/s)進行測試,客戶端應用程式可能會成為瓶頸,因為機器的 CPU 或網路利用率已到達極限。 如果到了這一刻,您可以將用戶端應用程式向外延展至多部伺服器,以繼續將 Azure Cosmos DB 帳戶再往前推進一步。
使用基於名稱的位址
使用基於名稱的位址,其中連結格式為
dbs/MyDatabaseId/colls/MyCollectionId/docs/MyDocumentId,以避免擷取用於建構連結的所有資源的 ResourceId,請勿使用 SelfLinks (_self),其格式為dbs/<database_rid>/colls/<collection_rid>/docs/<document_rid>。 此外,隨著這些資源被重新建立(可能名稱相同),快取可能無濟於事。調整查詢/閱讀訂閱的頁面大小以提升效能
當使用讀取導向功能(例如 readDocuments)進行大量讀取文件,或發出 SQL 查詢時,若結果集過大,結果會以分段方式回傳。 預設情況下,結果會以 100 個項目或 1 MB 為單位回傳,以先達到的限制為準。
為了減少取得所有適用結果所需的網路往返次數,你可以使用 x-ms-max-item-count 請求標頭將頁面大小增加到最多 1000。 當你只需要顯示少數結果,例如使用者介面或應用程式 API 每次只回傳 10 個結果時,你也可以將頁面大小縮小到 10,以降低讀取和查詢所消耗的吞吐量。
你也可以使用 setPageSize 方法設定頁面大小。
索引政策
將未使用的路徑排除於索引編製外以加快寫入速度
Azure Cosmos DB 的索引政策允許你透過索引路徑(setIncludedPaths 和 setExcludedPaths)指定哪些文件路徑要包含或排除。 在事先知道查詢模式的案例中,使用檢索路徑可改善寫入效能並降低索引儲存空間,因為檢索成本與檢索的唯一路徑數目直接相互關聯。 例如,以下程式碼示範了如何使用「*」通配字元來排除整個文件區段(子樹)不被索引。
Sync Java SDK V2 (Maven com.microsoft.azure::azure-documentdb)
Index numberIndex = Index.Range(DataType.Number); numberIndex.set("precision", -1); indexes.add(numberIndex); includedPath.setIndexes(indexes); includedPaths.add(includedPath); indexingPolicy.setIncludedPaths(includedPaths); collectionDefinition.setIndexingPolicy(indexingPolicy);如需詳細資訊,請參閱 Azure Cosmos DB 索引編製原則。
Throughput
衡量和調整以降低請求單位每秒的使用量
Azure Cosmos DB 提供許多的資料庫作業,包括使用 UDF、預存程序和觸發程序進行關聯式和階層式查詢,而這些作業全都是對資料庫集合內的文件來進行。 與上述各項作業相關聯的成本,會因為完成作業所需的 CPU、IO 和記憶體而不同。 您不需要考慮和管理硬體資源,您可以將要求單位 (RU) 想成是執行各種資料庫作業以及服務應用程式要求時所需的資源數量。
輸送量是根據為每個容器所設定的要求單位數量來佈建。 要求單位消耗量是以每秒的速率來計算。 如果應用程式的速率超過為其容器佈建的要求單位速率,便會受到限制,直到該速率降到容器的佈建層級以下。 如果您的應用程式需要較高的輸送量,您可以藉由佈建其他的要求單位來增加輸送量。
查詢的複雜度會影響操作所耗用的請求單位數量。 述詞數目、述詞性質、UDF 數目,以及來源資料集的大小,全都會影響查詢作業的成本。
要衡量任何操作(建立、更新或刪除)的開銷,檢查 x-ms-request-charge 標頭(或 ResourceResponse<T> 或 FeedResponse<T> 中等效的 RequestCharge 屬性,以衡量這些操作所消耗的請求單元數量)。
Sync Java SDK V2 (Maven com.microsoft.azure::azure-documentdb)
ResourceResponse<Document> response = client.createDocument(collectionLink, documentDefinition, null, false); response.getRequestCharge();在此標頭中傳回的要求費用是佈建輸送量的一小部分。 例如,若你已配置 2000 RU/s,且前一查詢回傳 1,000 份 1KB 文件,則操作成本為 1000。 因此在一秒內,伺服器在對後續要求進行速率限制前,只會接受兩個這類要求。 如需詳細資訊,請參閱要求單位和要求單位計算機。
處理速率限制/要求速率太大
當用戶端嘗試超過帳戶保留的輸送量時,伺服器的效能不會降低,而且不會使用超過保留層級的輸送量容量。 伺服器將預先使用 RequestRateTooLarge (HTTP 狀態碼 429) 來結束要求,並傳回 x-ms-retry-after-ms 標頭,以指出使用者重試要求之前必須等候的時間量 (毫秒)。
HTTP Status 429, Status Line: RequestRateTooLarge x-ms-retry-after-ms :100SDK 全都隱含地攔截這個回應,採用伺服器指定的 retry-after 標頭,並重試此要求。 除非有多個用戶端同時存取您的帳戶,否則下次重試將會成功。
如果你有多個用戶端累積運作穩定高於請求速率,用戶端內部預設的重試次數為 9 可能不足;此時,用戶端會拋出狀態碼為 429 的 DocumentClientException 給應用程式。 預設的重試次數可以透過 ConnectionPolicy 實例上的 setRetryOptions 來更改。 預設情況下,若請求持續超過請求速率,則在累積等待 30 秒後,狀態碼為 429 的 DocumentClientException 會被回傳。 即使目前的重試計數小於最大重試計數 (預設值 9 或使用者定義的值),也會發生這種情況。
雖然自動重試行為有助於改善大部分應用程式的恢復功能和可用性,但是在進行效能基準測試時可能會有所歧異 (尤其是在測量延遲時)。 如果實驗達到伺服器節流並導致用戶端 SDK 以無訊息模式重試,則用戶端觀察到的延遲將會突然增加。 若要避免效能實驗期間的延遲尖峰,測量每個作業所傳回的費用,並確保要求是以低於保留要求速率的方式運作。 如需詳細資訊,請參閱 要求單位。
輸送量較高之少量文件的設計
指定之作業的要求費用 (要求處理成本) 與文件大小直接相互關聯。 大型文件的作業成本高於小型文件的作業成本。
後續步驟
若要深入了解如何針對規模和高效能設計您的應用程式,請參閱 Azure Cosmos DB 的資料分割與調整規模。