DocumentDB - 分割槽



當您的資料庫開始增長到超過 10GB 時,您可以透過簡單地建立新的集合,然後將您的資料分散或分割槽到越來越多的集合中來擴充套件。

遲早,單個集合(容量為 10GB)將不足以容納您的資料庫。現在 10GB 可能聽起來不是一個很大的數字,但請記住,我們儲存的是 JSON 文件,它只是純文字,即使考慮到索引的儲存開銷,您也可以在 10GB 中容納大量純文字文件。

在可擴充套件性方面,儲存並不是唯一的關注點。S3 集合提供的集合最大吞吐量為每秒 2500 個請求單元。因此,如果您需要更高的吞吐量,那麼您還需要透過使用多個集合進行分割槽來擴充套件。擴充套件分割槽也稱為**水平分割槽**。

Azure DocumentDB 可以使用多種方法對資料進行分割槽。以下是最常見的策略 -

  • 溢位分割槽
  • 範圍分割槽
  • 查詢分割槽
  • 雜湊分割槽

溢位分割槽

溢位分割槽是最簡單的策略,因為它沒有分割槽鍵。當您不確定很多事情時,它通常是一個不錯的選擇。您可能不知道您是否需要擴充套件到單個集合之外,或者您可能需要新增多少個集合,或者您可能需要新增的速度有多快。

  • 溢位分割槽從單個集合開始,並且沒有分割槽鍵。

  • 集合開始增長,然後繼續增長,然後繼續增長,直到您開始接近 10GB 的限制。

  • 當您達到 90% 的容量時,您會溢位到一個新的集合並開始使用它來儲存新文件。

  • 一旦您的資料庫擴充套件到大量集合,您可能需要轉向基於分割槽鍵的策略。

  • 當您這樣做時,您需要透過根據您遷移到的任何策略將文件移動到不同的集合來重新平衡您的資料。

範圍分割槽

最常見的策略之一是範圍分割槽。使用這種方法,您可以確定文件分割槽鍵可能落在其中的值範圍,並將文件定向到與該範圍對應的集合。

  • 日期通常與此策略一起使用,您可以在其中建立一個集合來儲存落在定義的日期範圍內的文件。當您定義足夠小的範圍時,您有信心沒有集合會超過其 10GB 的限制。例如,可能有一種情況是單個集合可以合理地處理整個月的文件。

  • 也可能是大多數使用者都在查詢當前資料,這將是本月或可能上個月的資料,但使用者很少搜尋更舊的資料。因此,您從 6 月開始使用 S3 集合,這是您可以購買的最昂貴的集合,並且可以提供您所能獲得的最佳吞吐量。

  • 在 7 月,您購買另一個 S3 集合來儲存 7 月份的資料,並且還將 6 月份的資料縮減到更便宜的 S2 集合。然後在 8 月,您獲得另一個 S3 集合並將 7 月份縮減到 S2,並將 6 月份一直縮減到 S1。它會持續下去,月復一月,您始終保持當前資料可用以獲得高吞吐量,而舊資料則以較低的吞吐量保持可用。

  • 只要查詢提供了分割槽鍵,就只會查詢需要查詢的集合,而不是像溢位分割槽那樣查詢資料庫中的所有集合。

查詢分割槽

使用查詢分割槽,您可以定義一個分割槽對映,該對映根據文件的分割槽鍵將文件路由到特定的集合。例如,您可以按區域進行分割槽。

  • 將所有美國文件儲存在一個集合中,所有歐洲文件儲存在另一個集合中,並將來自任何其他區域的所有文件儲存在第三個集合中。

  • 使用此分割槽對映,查詢分割槽解析器可以根據分割槽鍵(包含在每個文件中的區域屬性)確定要建立文件的集合以及要查詢的集合。

雜湊分割槽

在雜湊分割槽中,分割槽是根據雜湊函式的值分配的,允許您在多個分割槽之間均勻分佈請求和資料。

這通常用於對大量不同客戶端生成或使用的產生的資料進行分割槽,並且對於儲存使用者配置檔案、目錄項等很有用。

讓我們來看一個使用 .NET SDK 提供的 RangePartitionResolver 進行範圍分割槽的簡單示例。

**步驟 1** - 建立一個新的 DocumentClient,我們將在 CreateCollections 任務中建立兩個集合。一個將包含使用者 ID 以 A 到 M 開頭的使用者的文件,另一個將包含使用者 ID 以 N 到 Z 開頭的使用者的文件。

private static async Task CreateCollections(DocumentClient client) {
   await client.CreateDocumentCollectionAsync(“dbs/myfirstdb”, new DocumentCollection {
      Id = “CollectionAM” }); 
		
   await client.CreateDocumentCollectionAsync(“dbs/myfirstdb”, new DocumentCollection {
      Id = “CollectionNZ” }); 
}

**步驟 2** - 為資料庫註冊範圍解析器。

**步驟 3** - 建立一個新的 RangePartitionResolver<string>,這是我們的分割槽鍵的資料型別。建構函式採用兩個引數,分割槽鍵的屬性名稱和一個字典,即分片對映或分割槽對映,它只是我們為解析器預定義的範圍和相應集合的列表。

private static void RegisterRangeResolver(DocumentClient client) {

   //Note: \uffff is the largest UTF8 value, so M\ufff includes all strings that start with M.
		
   var resolver = new RangePartitionResolver<string>(
      "userId", new Dictionary<Range<string>, string>() {
      { new Range<string>("A", "M\uffff"), "dbs/myfirstdb/colls/CollectionAM" },
      { new Range<string>("N", "Z\uffff"), "dbs/myfirstdb/colls/CollectionNZ" },
   });
	
   client.PartitionResolvers["dbs/myfirstdb"] = resolver;
 }

這裡有必要對最大可能的 UTF-8 值進行編碼。否則,第一個範圍將不匹配任何 Ms,除了單個 M,第二個範圍中的 Z 也一樣。因此,您可以將此處的編碼值視為匹配分割槽鍵的萬用字元。

**步驟 4** - 建立解析器後,使用當前 DocumentClient 為資料庫註冊它。為此,只需將其分配給 PartitionResolver 的 dictionary 屬性即可。

我們將針對資料庫建立和查詢文件,而不是像通常那樣針對集合建立和查詢文件,解析器將使用此對映將請求路由到相應的集合。

現在讓我們建立一些文件。首先,我們將為 userId Kirk 建立一個,然後為 Spock 建立一個。

private static async Task CreateDocumentsAcrossPartitions(DocumentClient client) { 
   Console.WriteLine(); 
   Console.WriteLine("**** Create Documents Across Partitions ****");
	
   var kirkDocument = await client.CreateDocumentAsync("dbs/myfirstdb", new { userId =
      "Kirk", title = "Captain" }); 
   Console.WriteLine("Document 1: {0}", kirkDocument.Resource.SelfLink);
	
   var spockDocument = await client.CreateDocumentAsync("dbs/myfirstdb", new { userId =
      "Spock", title = "Science Officer" });		
   Console.WriteLine("Document 2: {0}", spockDocument.Resource.SelfLink); 
}

此處的第一個引數是資料庫的自連結,而不是特定集合。如果沒有分割槽解析器,這是不可能的,但有了它,它就可以無縫地工作。

兩個文件都儲存到資料庫 myfirstdb 中,但我們知道 Kirk 儲存在 A 到 M 的集合中,Spock 儲存在 N 到 Z 的集合中,如果我們的 RangePartitionResolver 工作正常。

讓我們從 CreateDocumentClient 任務中呼叫這些,如下面的程式碼所示。

private static async Task CreateDocumentClient() {
   // Create a new instance of the DocumentClient 
   using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
      await CreateCollections(client);  
      RegisterRangeResolver(client);  
      await CreateDocumentsAcrossPartitions(client); 
   } 
}

執行上述程式碼後,您將收到以下輸出。

**** Create Documents Across Partitions **** 
Document 1: dbs/Ic8LAA==/colls/Ic8LAO2DxAA=/docs/Ic8LAO2DxAABAAAAAAAAAA==/ 
Document 2: dbs/Ic8LAA==/colls/Ic8LAP12QAE=/docs/Ic8LAP12QAEBAAAAAAAAAA==/

如您所見,這兩個文件的自連結具有不同的資源 ID,因為它們存在於兩個單獨的集合中。

廣告

© . All rights reserved.