Azure Cosmos DB 中的資料分割和水平調整

適用于: Nosql Mongodb 卡珊多拉 小鬼 Table

Azure Cosmos DB 會使用資料分割來調整資料庫中的個別容器以符合您應用程式效能需求。 在資料分割中,系統會將容器中的項目分割為不同子集,稱為邏輯分割區。 邏輯分割區是根據與容器中每個項目相關聯的分割區索引鍵值而形成的。 邏輯分割區中的所有項目都有相同的分割區索引鍵值。

例如,容器會保存項目。 每個項目針對 UserID 屬性都會有唯一的值。 如果 UserID 用來作為容器中項目的分割區索引鍵,而且有 1,000 個唯一的 UserID 值,則系統會為該容器建立 1,000 個邏輯分割區。

除了決定項目邏輯分割區的分割區索引鍵之外,容器中的每個項目都會有項目識別碼 (其在邏輯分割區內是唯一的)。 透過結合分割區索引鍵和項目識別碼,會建立項目的索引,其能唯一識別該項目。 選擇分割區索引鍵是一個將影響應用程式效能的重要決策。

本文說明邏輯與實體分割區之間的關聯性。 其也會討論資料分割的最佳做法,並深入檢視水平縮放在 Azure Cosmos DB 中的運作方式。 雖然您不需要了解這些內部詳細資料,就可以選取您的分割區索引鍵,但我們還是加以涵蓋,以讓您清楚了解 Azure Cosmos DB 的運作方式。

邏輯分割區

邏輯分割區是由一組具有相同分割區索引鍵的項目所組成。 例如,在包含食物營養相關資料的容器中,所有項目都會包含一個 foodGroup 屬性。 您可以使用 foodGroup 作為容器的分割區索引鍵。 針對 foodGroup 具有特定值的項目群組,例如 Beef ProductsBaked ProductsSausages and Luncheon Meats,會形成不同的邏輯分割區。

邏輯分割區也會定義資料庫交易的範圍。 您可以使用含有快照集隔離的交易來更新邏輯分割區內的項目。 將新項目新增至容器時,系統會以透明方式建立新的邏輯分割區。 刪除底層資料時,您不需要擔心會刪除邏輯分割區。

您容器中的邏輯分割區數目沒有任何限制。 每個邏輯分割區最多可以儲存 20GB 的資料。 良好的分割區索引鍵選項有各式各樣的可能值。 例如,在所有項目都包含 foodGroup 屬性的容器中,Beef Products 邏輯分割區內的資料最多可成長至 20 GB。 選取具有各種可能值的分割區索引鍵可確保容器能夠調整規模。

您可以使用 Azure 監視器警示來監視邏輯分割區的大小是否已接近 20 GB

實體分割區

容器的調整方式是在實體分割區之間分配資料和輸送量。 就內部而言,會有一或多個邏輯分割區對應至單一實體分割區。 通常較小的容器具有許多邏輯分割區,但其只需要單一實體分割區。 與邏輯分割區不同的是,實體分割區是系統的內部實作,而且完全由 Azure Cosmos DB 管理。

您容器中的實體分割區數目取決於下列各項:

  • 所佈建的輸送量數目 (每個個別的實體分割區可以提供每秒最多 10,000 個要求單位的輸送量)。 實體分割區每秒 10,000 RU 的限制,表示邏輯分割區也會有每秒 10,000 RU 的限制,因為每個邏輯分割區只對應到一個實體分割區。

  • 總資料儲存體 (每個個別的實體分割區最多可以儲 50GB 的資料)。

注意

實體分割區是系統的內部實作,而且完全由 Azure Cosmos DB 管理。 開發解決方案時,請勿專注於實體分割區,因為您無法加以控制。 相反地,請將焦點放在您的分割區索引鍵上。 如果您選擇會將輸送量耗用量平均分配給邏輯分割區的分割區索引鍵,您將可確保跨實體分割區的輸送量耗用量是平衡的。

您容器中的邏輯分割區總數沒有任何限制。 當您佈建的輸送量或資料大小增加時,Azure Cosmos DB 將會分割現有的實體分割區,以自動建立新的實體分割區。 實體分割區分割不會影響應用程式的可用性。 分割實體分割區之後,單一邏輯分割區內的所有資料仍會儲存在相同的實體分割區上。 實體分割區分割只會在邏輯分割區與實體分割區之間建立新對應。

為容器佈建的輸送量會在實體分割區之間平均分配。 未平均分散要求的分割區索引鍵設計,可能會導致系統將太多要求導向一小部分的分割區,使其變成「經常性存取」。經常性存取分割區會使所佈建輸送量的使用效率不佳,這可能會導致速率限制和更高的成本。

您可以在 Azure 入口網站 [計量] 刀鋒視窗的 [儲存體] 區段中,看到容器的實體分割區:

檢閱實體分割區數目

在上述螢幕擷取畫面中,該容器具有 /foodGroup 作為分割區索引鍵。 圖表中的三個橫條個別代表一個實體分割區。 在影像中,[分割區索引鍵範圍] 等同於實體分割區。 選取的實體分割區包含前 3 個最大的邏輯分割區:Beef ProductsVegetable and Vegetable ProductsSoups, Sauces, and Gravies

如果您佈建 18,000 每秒要求單位 (RU/s) 的輸送量,則這三個實體分割區個別都可以利用總佈建輸送量的 1/3。 在選取的實體分割區內,邏輯分割區索引鍵 Beef ProductsVegetable and Vegetable ProductsSoups, Sauces, and Gravies 合起來可以利用實體分割區佈建的 6,000 RU/S。 因為佈建的輸送量會在容器的實體分割區之間平均分配,所以請務必選擇正確的邏輯分割區索引鍵,以選擇能平均分配輸送量耗用量的分割區索引鍵。

管理邏輯分割區

Azure Cosmos DB 會以透明的方式自動管理在實體分割區上的邏輯分割區放置,以便有效率地滿足容器的可擴縮性和效能需求。 當應用程式的輸送量和儲存體需求增加時,Azure Cosmos DB 就會移動邏輯分割區,以自動將負載分散到更多實體分割區上。 您可以深入了解實體分割區

Azure Cosmos DB 會使用雜湊型資料分割,來將邏輯分割區分散到實體分割區上。 Azure Cosmos DB 會對項目的分割區索引鍵值進行雜湊處理。 雜湊的結果會決定實體分割區。 Azure Cosmos DB 會在實體分割區上平均配置分割區索引鍵雜湊的索引鍵空間。

僅允許針對單一邏輯分割區中的項目進行交易 (在預存程序或觸發程序中)。

複本集

每個實體分割區都是由一組複本所組成,其也稱為複本集。 每個複本都會裝載資料庫引擎的執行個體。 複本集讓實體分割區內儲存的資料都具耐久性、高度可用且一致。 組成實體分割區的每個複本都會繼承分割區的儲存體配額。 實體分割區的所有複本會集體支援配置給實體分割區的輸送量。 Azure Cosmos DB 會自動管理複本集。

通常,較小的容器只需要單一實體分割區,但其仍會有至少 4 個複本。

下圖顯示如何將邏輯分割區對應至全域散發的實體分割區。 映像中的分割集指的是跨多個區域管理相同邏輯分割區索引鍵的一組實體分割區:

示意圖:Azure Cosmos DB 資料分割

選擇分割區索引鍵

分割區索引鍵有兩個元件:分割區索引鍵路徑分割區索引鍵值。 例如,假設有一個項目 { "userId" : "Andrew", "worksFor": "Microsoft" } 如果您選擇 "userId" 作為分割區索引鍵,則下列為兩個分割區索引鍵元件:

  • 分割區索引鍵路徑 (例如:"/userId")。 分割區索引鍵路徑接受英數字元和底線 (_) 字元。 您也可以使用標準路徑標記法 (/) 來使用巢狀物件。

  • 分割區索引鍵值 (例如:"Andrew")。 分割區索引鍵值可以是字串或數值類型。

若要了解輸送量、儲存體和分割區索引鍵長度的限制,請參閱 Azure Cosmos DB 服務配額一文。

選取分割區索引鍵是 Azure Cosmos DB 中簡單但重要的設計選擇。 當您選取分割區索引鍵之後,就無法就地變更。 如果您需要變更分割區索引鍵,則應該將您的資料移至具有所需新分割區索引鍵的新容器。 (容器複製作業 可協助處理此程式。)

對於所有容器而言,您的分割區索引鍵應該:

  • 是具有不會變更之值的屬性。 如果屬性是您的分割區索引鍵,您便無法更新該屬性的值。

  • 應只包含 String 值,或是如果數字可能超出 IEEE 754 binary64 所述的雙精確度數字的界限,則數字應最好轉換為 StringJson 規格會指出為什麼使用此界限外數字通常會因為可能的互通性問題,而不是理想做法。 這些問題尤其與分割區索引鍵資料行有關,因為其不可變,必須在資料移轉後才能變更。

  • 具有較高的基數。 換句話說,屬性應該要有各式各樣的可能值。

  • 將要求單位 (RU) 耗用量和資料儲存體平均分配給所有邏輯分割區。 這可確保 RU 耗用量與儲存體會在實體分割區之間平均分配。

如果您在 Azure Cosmos DB 中需要多項目 ACID 交易,您必須使用預存程序或觸發程序。 所有 JavaScript 型的預存程序和觸發程序的範圍都是單一邏輯分割區。

注意

如果您只有一個實體分割區,分割區索引鍵的值可能不重要,因為所有查詢都會以相同的實體分割區為目標。

大量讀取容器的分割區索引鍵

對於大部分的容器而言,在挑選分割區索引鍵時,您只需要考慮上述準則。 不過,對於大型的大量讀取容器而言,建議您選擇經常在查詢中顯示為篩選的分割區索引鍵。 藉由在篩選述詞中包括分割區索引鍵,可以有效率地將查詢路由傳送至相關的實體分割區

如果您工作負載大部分的要求都是查詢,且大部分的查詢針對相同的屬性都具有相等的篩選,則這個屬性便是不錯的分割區索引鍵選擇。 例如,如果您經常執行會篩選 UserID 的查詢,則選取 UserID 作為分割區索引鍵將能減少跨分割區查詢的數目。

但是,如果您的容器很小,您的實體分割區可能不足以讓您需要擔心跨分割區查詢所帶來的效能影響。 Azure Cosmos DB 中最小的容器只需要一或兩個實體分割區。

如果您的容器可能會成長為具備多個實體分割區,則您應該挑選能將跨分割區查詢最小化的分割區索引鍵。 當下列任一項為真時,您的容器將需要一個以上的實體分割區:

  • 您的容器將會佈建超過 30,000 個 RU

  • 您的容器將會儲存超過 100 GB 的資料

使用項目識別碼作為分割區索引鍵

如果您的容器具有具備各式各樣可能值的屬性,該屬性便可能很適合作為分割區索引鍵。 這類屬性其中一個可能的範例是項目識別碼。 對於小型的大量讀取容器或任何大小的大量寫入容器而言,項目識別碼向來就是分割區索引鍵的絕佳選擇。

您容器中的每個項目都會有作為系統屬性的項目識別碼。 您可能會有代表您項目邏輯識別碼的其他屬性。 在許多情況下,這些也是絕佳的分割區索引鍵選擇,其原因與項目識別碼相同。

項目識別碼是很棒的分割區索引鍵選擇,原因如下:

  • 具有各式各樣可能的值 (每個項目都有一個唯一的項目識別碼)。
  • 因為每個項目都有唯一的項目識別碼,所以項目識別碼很適合用來平均分配 RU 耗用量和資料儲存體。
  • 您可以輕鬆地進行有效的點讀取,因為只要知道某個項目的項目識別碼,就能知道其分割區索引鍵。

選取項目識別碼作為分割區索引鍵時,應考慮的一些事項包括:

  • 如果項目識別碼是分割區索引鍵,其會成為整個容器的唯一識別碼。 您將無法擁有具有重複項目識別碼的項目。
  • 如果您有具有許多實體分割區的大量讀取容器,如果查詢具有搭配項目識別碼的相等篩選,其便會更加有效率。
  • 您無法跨多個邏輯分割區執行預存程序或觸發程序。

後續步驟