7 คะแนน โดย xguru 2024-08-09 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • rqlite เป็นฐานข้อมูลเชิงสัมพันธ์แบบกระจายโอเพนซอร์สน้ำหนักเบาที่เขียนด้วย Go
  • สร้างขึ้นบนโปรโตคอลฉันทามติ Raft และใช้ SQLite เป็น storage engine
  • ได้เริ่มการพัฒนา 9.0 แล้ว โดยตั้งเป้าลดการใช้ดิสก์ลงประมาณ 50%
  • เป้าหมายนี้จะทำได้ผ่านการปรับสถาปัตยกรรมระดับสูงเพื่อตัดสาเหตุหลักของการใช้ดิสก์ใน rqlite ออกไป

ตอนนี้อะไรคือสิ่งที่กินพื้นที่ดิสก์เป็นหลัก?

  • Raft log:
    • บันทึกการเปลี่ยนแปลงของระบบ
    • log นี้เป็นแกนหลักของระบบฉันทามติ Raft
  • ฐานข้อมูล SQLite สำหรับการทำงาน:
    • ฐานข้อมูลที่ใช้งานจริงซึ่ง rqlite ใช้เพื่อให้บริการการอ่านและเขียน
    • เมื่อคำสั่ง SQLite ถูก commit ลงใน Raft log สำเร็จ คำสั่งนั้นจะถูกนำไปใช้กับฐานข้อมูล SQLite สำหรับการทำงาน
  • สแนปช็อตของฐานข้อมูล SQLite สำหรับการทำงาน:
    • เพื่อป้องกันไม่ให้ Raft log เติบโตอย่างไม่จำกัด ระบบย่อย Raft ภายใน rqlite จะสร้างและจัดเก็บสำเนาฐานข้อมูล SQLite สำหรับการทำงาน ณ ช่วงเวลาหนึ่งเป็นระยะ
    • สำเนานี้เรียกว่า snapshot
    • เมื่อสร้าง snapshot แล้ว rqlite จะสามารถตัดทอน Raft log ได้
    • สำเนา snapshot นี้ถูกใช้โดย rqlite เพื่อกู้คืนโหนดเมื่อโหนดเริ่มทำงานใหม่ หรือถูกส่งไปยังโหนดอื่นเมื่อโหนดนั้นต้อง “ตามให้ทัน” สถานะของคลัสเตอร์ rqlite ที่มีอยู่
    • การสร้าง snapshot และการตัดทอน log เป็นแนวคิดหลักของระบบที่อิงกับ Raft

การออกแบบระดับสูงสำหรับ rqlite 9.0

  • กลยุทธ์หลักในการลดการใช้ดิสก์คือการตัดความจำเป็นในการเก็บสำเนา snapshot ของฐานข้อมูล SQLite สำหรับการทำงานในระบบ Raft ออกไป
  • Raft log ถูกตัดทอนเป็นระยะจากการสร้าง snapshot และจะหยุดโตหลังจากถึงจุดหนึ่ง แต่ฐานข้อมูล SQLite สำหรับการทำงานจะยังคงโตต่อไปเมื่อมีการเขียนข้อมูลเพิ่มขึ้น
  • และเนื่องจากสำเนา snapshot ของฐานข้อมูล SQLite มีขนาดเกือบเท่ากับฐานข้อมูล SQLite สำหรับการทำงาน ขนาดของมันจึงโตขึ้นเช่นกัน
  • ดังนั้น หากสามารถกำจัดสำเนา snapshot นี้ได้ rqlite จะใช้ดิสก์น้อยลง 50%
  • อย่างไรก็ตาม โหนด rqlite จำเป็นต้องมีสำเนา snapshot ในบางช่วงเวลา ซึ่งหลีกเลี่ยงไม่ได้
  • แล้วจะทำอย่างไรให้ข้ามการเก็บสำเนาไปได้ แต่ยังตอบโจทย์ความจำเป็นของการสร้างและกู้คืน snapshot?
  • เพื่อให้เข้าใจวิธีหลีกเลี่ยงการเก็บสำเนาเพิ่มระหว่างกระบวนการ snapshot จำเป็นต้องรู้ว่า rqlite รันฐานข้อมูล SQLite พื้นฐานในโหมด Write-Ahead Log(WAL)
  • ในการออกแบบ 9.0 ที่เสนอ ไฟล์ฐานข้อมูล SQLite สำหรับการทำงานหลัก (ไม่รวมไฟล์ WAL ที่เกี่ยวข้อง) และสำเนา snapshot ของระบบ Raft มีความเหมือนกันในเชิงตรรกะ
  • การใช้ข้อเท็จจริงนี้ทำให้ไม่จำเป็นต้องจัดเก็บสำเนา snapshot แยกต่างหากในระบบ Raft

แนวทางใหม่ในการสร้าง snapshot

  • การสร้าง snapshot และการทำ WAL checkpoint:
    • เมื่อถึงเวลาสร้าง snapshot rqlite จะทำ checkpoint ให้กับ Write-Ahead Log(WAL) ของฐานข้อมูล SQLite สำหรับการทำงาน
    • การเขียนทั้งหมดหลังจากนั้นจะถูกส่งไปยังไฟล์ WAL ใหม่ ทำให้ไฟล์ SQLite หลักคงสภาพไม่เปลี่ยนแปลงนับจากเวลาที่สร้าง snapshot
    • ผลลัพธ์คือจนกว่าจะเกิด snapshot ถัดไป ไฟล์ SQLite หลักจะแสดงสถานะ ณ เวลานั้นที่จำเป็นสำหรับที่เก็บ snapshot ของ Raft
    • แนวทางนี้ทำให้การอ่านและเขียนตามปกติใช้ไฟล์ SQLite และไฟล์ WAL ร่วมกัน ขณะที่ไฟล์ SQLite หลักที่ไม่เปลี่ยนแปลงทำหน้าที่เป็นชุดข้อมูลสำหรับที่เก็บ snapshot ของ Raft
    • ไม่จำเป็นต้องมีสำเนาเพิ่มเติมอีกต่อไป!
  • การเขียนข้อมูลอ้างอิงลงในที่เก็บ snapshot:
    • แทนที่จะคัดลอกไฟล์ SQLite ทั้งหมด rqlite จะเขียนข้อมูลอ้างอิง เช่น checksum ลงในที่เก็บ snapshot
    • ข้อมูลอ้างอิงนี้สามารถใช้ตรวจสอบได้ว่าไฟล์ SQLite หลักตรงกับสิ่งที่ที่เก็บ snapshot อ้างอิงไว้ทุกครั้งที่ต้องการข้อมูล snapshot
      • (การตรวจสอบนี้ช่วยป้องกันบั๊ก ความผิดพลาดในการปฏิบัติการ หรือความเสียหายของดิสก์ แต่ไม่ใช่สิ่งจำเป็นอย่างเคร่งครัด)
  • การกู้คืนจาก snapshot:
    • ตามที่กล่าวไปก่อนหน้านี้ การเขียนทั้งหมดหลังจากกระบวนการ snapshot จะถูกส่งไปยังไฟล์ WAL ดังนั้นไฟล์ SQLite หลักจึงพร้อมใช้งานสำหรับกระบวนการกู้คืนจาก snapshot เช่น เมื่อโหนดเริ่มใหม่ หรือเมื่อต้องส่ง snapshot ไปยังโหนดอื่น
    • กล่าวคือ ไฟล์ SQLite หลัก (ไม่นับไฟล์ WAL ที่เกี่ยวข้อง) จะยังคงเหมือนกันในเชิงตรรกะกับสิ่งที่ rqlite จะเขียนลงในที่เก็บ Raft snapshot หากมันสร้างสำเนาซ้ำจริง ๆ
  • การออกแบบใหม่นี้ถูกเรียกว่า “reference snapshot”

การปรับปรุงเพิ่มเติม

  • reference snapshot จะนำมาซึ่งการปรับปรุงสำคัญอื่น ๆ อีกหลายอย่าง
  • สร้าง snapshot ได้เร็วขึ้น: เนื่องจากเขียนข้อมูลลงในที่เก็บ Raft snapshot เพียงเล็กน้อย กระบวนการ snapshot จะเร็วขึ้นมาก
    • จะประกอบด้วยเวลาในการทำ SQLite WAL checkpoint (ซึ่งปกติสั้นมาก) และเวลาในการคำนวณ checksum
    • ไม่จำเป็นต้องคัดลอกข้อมูล SQLite ปริมาณมากไปยังที่เก็บ snapshot ทุกครั้งที่สร้าง snapshot
    • เมื่อรู้ว่าการเขียนไปยัง rqlite จะถูกบล็อกระหว่างกระบวนการ snapshot ข้อดีของ snapshot ที่เร็วขึ้นก็จะชัดเจน
  • เริ่มทำงานใหม่ได้เร็วขึ้น: แม้แต่โหนดที่มีข้อมูล SQLite หลาย GB ก็จะเริ่มทำงานใหม่ได้เร็วขึ้นมาก
    • ปัจจุบันเมื่อเริ่มใหม่ rqlite ต้องกู้คืนไฟล์ฐานข้อมูล SQLite สำหรับการทำงานจากสำเนาในที่เก็บ Raft snapshot
    • แต่ด้วยการออกแบบใหม่นี้ เมื่อเริ่มต้น ไฟล์ฐานข้อมูล SQLite สำหรับการทำงานจะอยู่ในตำแหน่งที่ถูกต้องอยู่แล้ว
    • อย่างมากที่สุด rqlite เพียงแค่ต้องเปรียบเทียบ checksum ในที่เก็บ snapshot กับ checksum ของฐานข้อมูล SQLite สำหรับการทำงาน
    • ระบบขนาดหลาย GB ควรเริ่มทำงานใหม่ได้ภายในไม่กี่วินาที

ขั้นตอนถัดไป

  • การย้ายไปสู่ rqlite 9.0 จะเป็นก้าวสำคัญในการเพิ่มประสิทธิภาพของ rqlite
  • คาดว่าการนำ reference snapshot มาใช้จะช่วยลดการใช้ดิสก์อย่างมาก เพิ่มความเร็วในการสร้าง snapshot และปรับปรุงเวลาเริ่มทำงานใหม่ของโหนด
  • ยังมีรายละเอียดอีกมากที่ต้องจัดการให้ถูกต้อง เช่น การจัดการ SQLite WAL, การอัปเกรดอย่างราบรื่นจากรีลีสก่อนหน้า, และการเลือก checksum
  • ดังนั้นโปรดติดตามอัปเดตเพิ่มเติมต่อไปขณะที่เดินหน้าสู่รีลีสใหญ่ครั้งนี้