ผลกระทบที่มองข้ามของขนาดข้อมูล

Dec 01 2022
ขอขอบคุณเป็นพิเศษสำหรับ Özgür Karakaya ที่ฉันร่วมเขียนบล็อกโพสต์นี้ด้วย PDP (หน้ารายละเอียดสินค้า) ใน Trendyol เป็นทีมที่รับผิดชอบในการให้ข้อมูลเกี่ยวกับผลิตภัณฑ์เฉพาะ

ขอขอบคุณเป็นพิเศษสำหรับÖzgür Karakayaที่ฉันร่วมเขียนบล็อกโพสต์นี้ด้วย

PDP (หน้ารายละเอียดสินค้า) ใน Trendyol เป็นทีมที่รับผิดชอบในการให้ข้อมูลเกี่ยวกับผลิตภัณฑ์เฉพาะ ข้อมูลนี้ประกอบด้วยราคา ขนาด สี หรือข้อมูลอื่นๆ ที่เกี่ยวข้องที่ลูกค้าต้องการทราบก่อนตัดสินใจซื้อ ข้อมูลสามารถนำเสนอได้สองวิธี วิธีแรกอยู่ในรูปแบบของหน้ารายละเอียดสินค้าเดียว ส่วนใหญ่เมื่อคุณคลิกที่ผลิตภัณฑ์และนำทางไปยังหน้าที่แสดงข้อมูลผลิตภัณฑ์เฉพาะ ทีมงานยังรับผิดชอบในการให้ข้อมูลรายละเอียดสินค้าแก่มุมมองอื่นๆ บนเว็บไซต์ เช่น รายการโปรดของคุณ สินค้าแนะนำ และการชำระเงิน ทั้งสองวิธีได้รับการจัดการโดยบริการเดียวที่เรียกว่า Product Detail API ที่สนับสนุนโดยฐานข้อมูล Couchbase NoSQL ที่ให้บริการคำขอเดียว (หน้ารายละเอียดผลิตภัณฑ์เดียว) เช่นเดียวกับคำขอจำนวนมาก (รายการโปรด ฯลฯ ..)

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

นี่คือการเดินทาง

การระดมสมองและการวิเคราะห์

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

  • การเพิ่มประสิทธิภาพขนาดข้อมูล
  • เน้นโดเมนเนื้อหาจำนวนมาก

ด้านล่างนี้คือไดอะแกรมของสถาปัตยกรรมที่มีอยู่และใหม่ในขณะนั้น:

สถาปัตยกรรม AS-IS และสถาปัตยกรรมที่เสนอ

กล่องประด้านนอกกำหนดขอบเขตของบริการ ขอให้สังเกตว่าในภาพประกอบแรกนี้ บริการหนึ่งรับผิดชอบในการจัดการไปป์ไลน์ของการดำเนินงานทั้งหมด การเพิ่มประสิทธิภาพคือการแบ่งไปป์ไลน์การแปลงออกเป็นสองกระบวนการแยกกันตามที่เห็นในสถาปัตยกรรมที่สอง: กระบวนการแปลงตามเวลาดัชนีและบริการเนื้อหาจำนวนมาก หลังเป็นบริการอ่านที่จัดการคำขอ HTTP ขั้นตอนแรกกลายเป็นกระบวนการที่ขับเคลื่อนด้วยเหตุการณ์ที่อ่านข้อมูลจาก ProductContent CB (Source Of Truth) ประมวลผลบางส่วน จากนั้นจัดเก็บไว้ใน Counchbase Bucket เพื่อให้ส่วนหลังใช้ แต่เพิ่มเติมในภายหลัง
ภายใต้สถาปัตยกรรมใหม่ที่เสนอ ประโยชน์หลักคือกระบวนการรันไทม์จะได้รับการปรับให้เหมาะสม ซึ่งจะลดเวลาตอบสนองของบริการ

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

ป.ล. ฉันใช้คำว่ารันไทม์ที่นี่ค่อนข้างหลวม ในบริบทของบล็อกนี้ เรากำลังกำหนดรันไทม์เป็นลำดับของการดำเนินการที่ทริกเกอร์โดยคำขอ HTTP ที่เข้ามา

โซลูชันที่มีอยู่

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

เหตุการณ์ Couchbase:

Couchbase Eventing Service เป็นเฟรมเวิร์กเพื่อดำเนินการกับการเปลี่ยนแปลงข้อมูลตามเวลาจริง เหตุการณ์คือการเปลี่ยนแปลงข้อมูลในคลัสเตอร์ Couchbase

Couchbase Eventing ดูเหมือนจะเหมาะกับเราเพราะคุณสามารถ :

  • เผยแพร่การเปลี่ยนแปลงไปยังระบบอื่นๆ
  • เติมเต็มเอกสารตามเวลาจริง
  • ไม่ต้องบำรุงรักษา

ไม่มีแจ็คพอต

โซลูชันของเรา (ตัวแปลงข้อมูลเนื้อหาจำนวนมาก)

แรงบันดาลใจจากCB Elasticsearch Connector

Couchbase Elasticsearch Connector จะจำลองเอกสารของคุณจาก Couchbase Server ไปยัง Elasticsearch ในแบบเรียลไทม์ ตัวเชื่อมต่อใช้ Database Change Protocol (DCP) ประสิทธิภาพสูงเพื่อรับการแจ้งเตือนเมื่อเอกสารมีการเปลี่ยนแปลงใน Couchbase

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

โปรดทราบว่าโซลูชันจำเป็นต้องสามารถ:

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

มีหลายสิ่งที่ต้องแกะที่นี่ ขอสรุปก่อน:

สถาปัตยกรรมขั้นสุดท้าย

สถาปัตยกรรมข้างต้นแสดงวิธีแก้ปัญหาขั้นสุดท้าย ในที่สุด บริการรายละเอียดสินค้าจะจัดการคำขอเดียว ในขณะที่บริการเนื้อหาจำนวนมากจะจัดการคำขอจำนวนมาก บริการได้รับการสนับสนุนโดยแหล่งที่มาของโซฟาที่แตกต่างกัน ในขณะที่ProductContent CBแสดงถึงแหล่งที่มาของความจริงProductSummary CBแสดงถึงเวอร์ชันที่ประมวลผลล่วงหน้าโดยสรุป การแปลงจะได้รับการจัดการในBulk Content Data Converterแบบเกือบเรียลไทม์ผ่านการยอมรับการกลายพันธุ์ของเอกสารจากคิว DCP การกลายพันธุ์ของเอกสารแต่ละครั้งแสดงถึงสถานะของเอกสารหลังจากการอัพเดตเกิดขึ้น นี่เป็นอีกวิธีหนึ่งที่จะบอกว่าตัวแปลงจะได้รับเอกสารที่อัปเดตทั้งหมดจากProductContent CB โดยอัตโนมัติในการอัปเดตแต่ละครั้ง

เพื่อให้เข้าใจว่าโซลูชันนี้ปรับขนาดได้อย่างไร ควรดูที่ไฟล์กำหนดค่าของตัวแปลง:

{
  "group": {
    "name": "v20220909", 
    "membership": {
      "memberNumber": 1, 
      "totalMembers": n
    },
    "limit": {
      "bytes": "5m",
      "actions": 100,
      "timeout": "1m",
      "concurrency": 2
    },
    "version": 1,
    "ignoreDelete": false
  },
  "dcp": {
    "sourceConfig": {
      "hosts": ["source_couchbase_host"],
      "network": "auto",
      "bucket": "bucketName",
      "metadataBucket": "metadataBucketName",
      "scope": "",
      "collections": [],
      "compression": true,
      "flowControlBuffer": "16m",
      "persistencePollingInterval": "100ms"
    },
    "targetConfig": {
      "hosts": ["taget_couchbase_host"],
      "bucket": "targetBucketName"
    }
  }
}

การกำหนดค่าที่สำคัญอีกชิ้นหนึ่งคือgroup.nameซึ่ง แสดงถึงกลุ่มผู้บริโภคที่จัดเก็บออฟเซ็ต คิดเหมือนกลุ่มผู้บริโภคของคาฟคา การเปลี่ยนแปลงการกำหนดค่านี้จะรีเซ็ตดัชนีออฟเซ็ต ซึ่งหมายความว่าสถานะฐานข้อมูลทั้งหมดจะถูกส่งผ่านคิว DCP การดำเนินการนี้เป็นประโยชน์อย่างยิ่งเมื่อจำเป็นต้องอัปเดตโมเดลเอกสาร การเพิ่มหรือลบฟิลด์ใหม่ออกจากที่เก็บข้อมูลเป้าหมายจำเป็นต้องมีการอัปเดตทั้งหมดในเอกสารที่จัดเก็บทั้งหมด ซึ่งรวมถึงเอกสารที่ปกติแล้วจะไม่ได้รับการอัปเดตตามปกติในที่เก็บข้อมูลเป้าหมาย เนื่องจากจะไม่มีการกลายพันธุ์เกิดขึ้นในเอกสารต้นฉบับ นอกจากนี้ยังสามารถทำหน้าที่เป็นกลไกสร้างฐานข้อมูลใหม่ทั้งหมดในกรณีที่ข้อมูลเสียหายอย่างรุนแรง

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดค่า โปรดดูที่ลิงค์เอกสารประกอบ

จุดเพิ่มประสิทธิภาพอีกประการหนึ่งคือการลดขนาดเอกสารเป้าหมายโดยใช้ตัวย่อหรืออักขระเดี่ยวเป็นโหนด JSON ผู้เชี่ยวชาญโดเมนและ PM ไม่คาดว่าจะเข้าใจเอกสารนี้ และนี่คือเหตุผลที่เราสามารถหลีกเลี่ยงการแฮ็กที่ชั่วร้ายเช่นนี้ได้ ด้านล่างนี้เป็นตัวอย่างของเอกสาร:

เอกสารเป้าหมาย

และ ณ วันที่ 31 ตุลาคม ผลลัพธ์คือ...

ขนาดฝากข้อมูลก่อนและหลัง

การแฮ็กง่ายๆ นี้ช่วยให้เราลดขนาด Bucket จาก 2.92TB เป็น 595GB ได้! ลดขนาดการกลิ้งลงประมาณ 80%!
เราต้องสังเกตว่าจำนวนเอกสารในฐานข้อมูลเป้าหมายลดลงประมาณ 12 ล้าน เหตุผลคือเราไม่รวมผลิตภัณฑ์ที่หมดสต็อกซึ่งไม่ได้รับการอัปเดตเป็นเวลา 12 เดือน ในซอร์สบัคเก็ต เราอาจยังต้องการเอกสารเหล่านั้น แต่คงไม่มีเหตุผลที่จะรวมไว้ที่นี่ ดังนั้นจำนวนจึงแตกต่างกัน

การตรวจสอบและประสิทธิภาพ

จนถึงขณะนี้เรามีวิธีแก้ปัญหาและดำเนินการแล้ว แต่เราจะบอกได้อย่างไรว่ามีประสิทธิภาพเพียงพอหรือไม่ จะเกิดอะไรขึ้นถ้าสมมุติฐานกำลังทำ Conversion แต่ช้ากว่า 2 วินาที นั่นจะเป็นหายนะ! ความสม่ำเสมอดังกล่าวจะรั่วไหลไปยัง UI ของเว็บไซต์และส่งผลกระทบอย่างรุนแรงต่อประสบการณ์ของผู้ใช้ ไม่สามารถทริกเกอร์การเปลี่ยนแปลงบนฐานข้อมูลการผลิตด้วยตนเองได้ และไม่ควรเป็นวิธีทดสอบตั้งแต่แรก จำเป็นต้องมีวิธีการที่เป็นระบบเพื่อระบุแหล่งที่มาของความล่าช้าหากเกิดขึ้น ความล่าช้าเกิดขึ้นเพราะความแออัดในคิว DCP หรือไม่ หรือเป็นเพราะตัวแปลงมีข้อผิดพลาดบางอย่าง?

เพื่อตอบคำถามเหล่านี้ เราได้แนะนำเมตริกสามรายการดังที่แสดงในรูปด้านล่าง:

เมตริกการตรวจสอบ

เอกสารต้นฉบับมีการประทับเวลาของการอัปเดตครั้งล่าสุด เราเรียกว่าLMD (วันที่แก้ไขล่าสุด) เมื่อตัวแปลงได้รับการกลายพันธุ์แล้ว เวลา “ กำลังรอคิว DCP”สามารถคำนวณได้อย่างง่ายดายโดยการลบLMD ออก จากtime.now( ) เมตริกจะเปิดเผยต่อ Prometheus ดังแสดงในกราฟด้านล่าง:

เมตริกเวลาแฝงของตัวแปลงเนื้อหาจำนวนมาก

ข้อจำกัด:

จำได้ไหมที่ฉันพูดไปก่อนหน้านี้ว่าการปรับขนาดเป็นเพียงเรื่องของการเพิ่มจำนวนตัวแปลงทั้งหมด สิ่งนี้มาพร้อมกับข้อแม้เล็กน้อย: การกำหนดค่าของโซลูชันเป็นแบบเดินสายเล็กน้อยกับโครงสร้างพื้นฐานที่พูดด้วย การปรับสมดุลอัตโนมัติของผู้บริโภคในคิว DCP และการกระจายผู้บริโภคผ่าน vBuckets นั้นเดินสายไปยังการกำหนดค่าคงที่ที่ผู้บริโภคมีเมื่อเริ่มต้น ในการเปลี่ยนแปลงนั้นจำเป็นต้องเปลี่ยนไฟล์การกำหนดค่าเองซึ่งต้องมีการปรับใช้ใหม่ นอกจากนี้ ผู้บริโภคแต่ละรายต้องการไฟล์การกำหนดค่าแบบสแตติกของตนเอง ซึ่งหมายความว่าผู้บริโภคแต่ละรายต้องการ - ในคำศัพท์ของ Kubernetes - ที่จะมีไฟล์ทรัพยากรการปรับใช้ของตนเอง ใน Trendyol เราใช้ ArgoCD กับ Kustomize อย่างกว้างขวางเพื่อจัดการการปรับใช้ของเรา การปรับขนาดโซลูชันจำเป็นต้องเพิ่ม — ในคำศัพท์ ArgoCD — ชุดแอปพลิเคชันใหม่
อย่างไรก็ตาม จนถึงขณะนี้ผู้บริโภคจำนวน 8 คนของเรากำลังจัดการกับภาระงานจำนวนมากด้วยประสิทธิภาพที่ใกล้เคียงเรียลไทม์ แต่เมื่อซอร์สบัคเก็ตใหญ่ขึ้นและจำนวนการกลายพันธุ์ก็เพิ่มขึ้น จึงจำเป็นต้องกำหนดค่าผู้บริโภคใหม่ด้วยตนเอง

การใช้งานทีมอื่น ๆ ภายในองค์กร

ด้วยความมั่นใจเกี่ยวกับตัวเชื่อมต่อ CB-to-CB ที่พัฒนาขึ้น ทีม PDP จึงตัดสินใจนำเสนอต่อทีมอื่นๆ ภายใน Trendyol ทีมได้รับข้อเสนอแนะในเชิงบวกมากมาย และก่อนที่เราจะรู้ตัว ทีมค้นหาตัดสินใจแยกโครงการและใช้ในโดเมนของพวกเขา ซึ่งพวกเขาเก็บเหตุการณ์โดเมนไว้ในฐานข้อมูลโซฟาและใช้ตัวเชื่อมต่อ CB-to-CB เพื่อสร้างโมเดลเอกสารอื่น เพื่อใช้ในภายหลัง การนำโซลูชันที่พัฒนาขึ้นภายในองค์กรมาใช้ดังกล่าวเป็นแรงบันดาลใจให้เราทุกคนก้าวไปข้างหน้า ปรับปรุงและปรับแต่งการใช้เทคโนโลยีของเราต่อไป

สมัครงานตำแหน่งว่างของเราที่นี่ !