DocumentDB - การแบ่งพาร์ติชัน

เมื่อฐานข้อมูลของคุณเริ่มเติบโตเกิน 10GB คุณสามารถขยายขนาดได้ง่ายๆโดยการสร้างคอลเลกชันใหม่จากนั้นกระจายหรือแบ่งพาร์ติชันข้อมูลของคุณในคอลเลคชันมากขึ้น

ไม่ช้าก็เร็วคอลเลกชันเดียวซึ่งมีความจุ 10GB จะไม่เพียงพอที่จะมีฐานข้อมูลของคุณ ตอนนี้ 10GB อาจฟังดูไม่เหมือนตัวเลขที่มากนัก แต่โปรดจำไว้ว่าเรากำลังจัดเก็บเอกสาร JSON ซึ่งเป็นเพียงข้อความธรรมดาและคุณสามารถใส่เอกสารข้อความธรรมดาจำนวนมากได้ใน 10GB แม้ว่าคุณจะพิจารณาค่าใช้จ่ายในการจัดเก็บข้อมูลสำหรับดัชนีก็ตาม

พื้นที่จัดเก็บไม่ใช่สิ่งเดียวที่ต้องกังวลในเรื่องความสามารถในการขยายขนาด ปริมาณงานสูงสุดที่มีอยู่ในคอลเลกชันคือสองและครึ่งพันหน่วยคำขอต่อวินาทีที่คุณได้รับจากคอลเล็กชัน S3 ดังนั้นหากคุณต้องการปริมาณงานที่สูงขึ้นคุณจะต้องขยายขนาดโดยแบ่งพาร์ติชันกับหลายคอลเลกชัน เรียกอีกอย่างว่าการแบ่งพาร์ติชันแบบปรับขนาดออกhorizontal partitioning.

มีหลายวิธีที่สามารถใช้สำหรับการแบ่งข้อมูลกับ Azure DocumentDB ต่อไปนี้เป็นกลยุทธ์ที่พบบ่อยที่สุด -

  • การแบ่งพาร์ติชัน Spillover
  • การแบ่งช่วง
  • ค้นหาการแบ่งพาร์ติชัน
  • การแบ่งพาร์ติชันแฮช

การแบ่งพาร์ติชัน Spillover

การแบ่งพาร์ติชัน Spillover เป็นกลยุทธ์ที่ง่ายที่สุดเนื่องจากไม่มีคีย์พาร์ติชัน มักจะเป็นทางเลือกที่ดีในการเริ่มต้นเมื่อคุณไม่แน่ใจเกี่ยวกับสิ่งต่างๆมากมาย คุณอาจไม่ทราบว่าคุณจะต้องปรับขนาดให้มากกว่าคอลเลกชั่นเดียวหรือไม่หรือต้องเพิ่มจำนวนคอลเลกชันหรือเร็วแค่ไหนในการเพิ่ม

  • การแบ่งพาร์ติชัน Spillover เริ่มต้นด้วยคอลเล็กชันเดียวและไม่มีคีย์พาร์ติชัน

  • คอลเลกชันเริ่มเติบโตและเพิ่มขึ้นเรื่อย ๆ และเพิ่มขึ้นเรื่อย ๆ จนกว่าคุณจะเริ่มเข้าใกล้ขีด จำกัด 10GB

  • เมื่อคุณมีความจุถึง 90 เปอร์เซ็นต์คุณจะล้นไปยังคอลเล็กชันใหม่และเริ่มใช้งานสำหรับเอกสารใหม่

  • เมื่อฐานข้อมูลของคุณขยายเป็นจำนวนคอลเลกชันที่มากขึ้นคุณอาจต้องการเปลี่ยนไปใช้กลยุทธ์ที่ใช้พาร์ติชันคีย์

  • เมื่อคุณทำเช่นนั้นคุณจะต้องปรับสมดุลข้อมูลของคุณใหม่โดยการย้ายเอกสารไปยังคอลเลคชันต่างๆตามกลยุทธ์ที่คุณจะย้ายไป

การแบ่งช่วง

หนึ่งในกลยุทธ์ที่พบบ่อยที่สุดคือการแบ่งช่วง ด้วยวิธีนี้คุณจะกำหนดช่วงของค่าที่คีย์พาร์ติชันของเอกสารอาจอยู่ในและกำหนดทิศทางเอกสารไปยังคอลเล็กชันที่ตรงกับช่วงนั้น

  • โดยทั่วไปแล้ววันที่จะใช้กับกลยุทธ์นี้ซึ่งคุณสร้างคอลเลกชันเพื่อเก็บเอกสารที่อยู่ในช่วงวันที่ที่กำหนด เมื่อคุณกำหนดช่วงที่มีขนาดเล็กพอคุณมั่นใจได้ว่าจะไม่มีคอลเลกชันใดเกินขีด จำกัด 10GB ตัวอย่างเช่นอาจมีสถานการณ์สมมติที่คอลเลกชันเดียวสามารถจัดการเอกสารได้อย่างสมเหตุสมผลตลอดทั้งเดือน

  • นอกจากนี้ยังอาจเป็นกรณีที่ผู้ใช้ส่วนใหญ่กำลังค้นหาข้อมูลปัจจุบันซึ่งอาจเป็นข้อมูลของเดือนนี้หรือเดือนที่แล้ว แต่ผู้ใช้มักไม่ค่อยค้นหาข้อมูลที่เก่ากว่ามากนัก ดังนั้นคุณจึงเริ่มต้นในเดือนมิถุนายนด้วยคอลเลกชัน S3 ซึ่งเป็นคอลเลกชั่นที่แพงที่สุดที่คุณสามารถซื้อและให้ปริมาณงานที่ดีที่สุดที่คุณจะได้รับ

  • ในเดือนกรกฎาคมคุณซื้อคอลเลกชัน S3 อีกชุดเพื่อจัดเก็บข้อมูลเดือนกรกฎาคมและคุณยังปรับขนาดข้อมูลเดือนมิถุนายนให้เป็นคอลเลคชัน S2 ที่ราคาไม่แพง จากนั้นในเดือนสิงหาคมคุณจะได้รับคอลเลกชั่น S3 อีกชุดและปรับขนาดกรกฎาคมลงเป็น S2 และมิถุนายนไปจนถึง S1 เป็นไปทุกเดือนโดยที่คุณจะเก็บรักษาข้อมูลปัจจุบันไว้เสมอสำหรับปริมาณงานที่สูงและข้อมูลเก่าจะยังคงมีอยู่ในปริมาณงานที่ต่ำลง

  • ตราบใดที่แบบสอบถามมีคีย์พาร์ติชันเฉพาะคอลเลกชันที่จำเป็นต้องสืบค้นเท่านั้นที่จะได้รับการสืบค้นและไม่ใช่คอลเล็กชันทั้งหมดในฐานข้อมูลเช่นเดียวกับที่เกิดขึ้นกับการแบ่งพาร์ติชันที่รั่วไหล

ค้นหาการแบ่งพาร์ติชัน

ด้วยการแบ่งพาร์ติชันการค้นหาคุณสามารถกำหนดพาร์ติชันแม็พที่กำหนดเส้นทางเอกสารไปยังคอลเลกชันเฉพาะตามคีย์พาร์ติชัน ตัวอย่างเช่นคุณแบ่งพาร์ติชันตามภูมิภาคได้

  • จัดเก็บเอกสารของสหรัฐอเมริกาทั้งหมดในคอลเลกชั่นเดียวเอกสารยุโรปทั้งหมดในคอลเลกชันอื่นและเอกสารทั้งหมดจากภูมิภาคอื่น ๆ ในคอลเล็กชันที่สาม

  • ใช้การแม็พพาร์ติชันนี้และตัวแก้ไขพาร์ติชันการค้นหาสามารถระบุได้ว่าคอลเล็กชันใดที่จะสร้างเอกสารและคอลเล็กชันใดที่จะสืบค้นโดยยึดตามพาร์ติชันคีย์ซึ่งเป็นคุณสมบัติของพื้นที่ที่มีอยู่ในเอกสารแต่ละฉบับ

การแบ่งพาร์ติชันแฮช

ในการแบ่งแฮชพาร์ติชันจะถูกกำหนดตามค่าของฟังก์ชันแฮชซึ่งช่วยให้คุณสามารถแจกจ่ายคำขอและข้อมูลในพาร์ติชันต่างๆได้อย่างเท่าเทียมกัน

โดยทั่วไปจะใช้เพื่อแบ่งพาร์ติชันข้อมูลที่ผลิตหรือใช้จากไคลเอนต์ที่แตกต่างกันจำนวนมากและมีประโยชน์สำหรับการจัดเก็บโปรไฟล์ผู้ใช้รายการแค็ตตาล็อก ฯลฯ

มาดูตัวอย่างง่ายๆของการแบ่งช่วงโดยใช้ RangePartitionResolver ที่จัดทำโดย. NET SDK

Step 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” }); 
}

Step 2 - ลงทะเบียนตัวแก้ไขช่วงสำหรับฐานข้อมูล

Step 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 ในช่วงที่สอง ดังนั้นคุณสามารถคิดว่าค่าที่เข้ารหัสที่นี่เป็นสัญลักษณ์แทนสำหรับการจับคู่คีย์พาร์ติชัน

Step 4- หลังจากสร้างตัวแก้ไขแล้วให้ลงทะเบียนสำหรับฐานข้อมูลด้วย DocumentClient ปัจจุบัน ในการทำเช่นนั้นให้กำหนดให้กับคุณสมบัติพจนานุกรมของ PartitionResolver

เราจะสร้างและสอบถามเอกสารกับฐานข้อมูลไม่ใช่คอลเลกชันอย่างที่คุณทำตามปกติตัวแก้ไขจะใช้แผนที่นี้เพื่อกำหนดเส้นทางคำขอไปยังคอลเล็กชันที่เหมาะสม

ตอนนี้มาสร้างเอกสารกัน ก่อนอื่นเราจะสร้างหนึ่งสำหรับ 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 ทรัพยากรที่แตกต่างกันเนื่องจากมีอยู่ในคอลเล็กชันสองชุดแยกกัน