- 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
- ดังนั้นโปรดติดตามอัปเดตเพิ่มเติมต่อไปขณะที่เดินหน้าสู่รีลีสใหญ่ครั้งนี้
1 ความคิดเห็น
rqlite - ฐานข้อมูลแบบกระจายน้ำหนักเบาที่สร้างบน SQLite