29 คะแนน โดย xguru 2021-10-18 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • เมื่อต้นปีนี้ Notion ล่มเป็นเวลา 5 นาที และได้ทำ PostgreSQL sharding ที่ดำเนินการมาเป็นเวลาหลายเดือน

→ เริ่มมีเสียงตอบรับทันทีว่าระบบเร็วขึ้นมาก

  • ตัดสินใจทำ sharding ตั้งแต่เมื่อไร

→ หลังจากเติบโตขึ้นหลายหมื่นเท่าในช่วง 5 ปีที่ผ่านมา Postgres monolith ที่ใช้งานได้ดีมาตลอดก็เริ่มเกินขีดความสามารถด้านปริมาณข้อมูล

→ VACUUM เริ่มถูกขัดจังหวะอย่างต่อเนื่อง และคาดว่าจะเกิด TXID wraparound ในไม่ช้า จึงเริ่มงาน sharding

  • ออกแบบ sharding scheme

→ sharding ระดับแอปพลิเคชัน

⇨ จะ shard ข้อมูลอะไรบ้าง

⇨ จะแบ่งข้อมูลโดย partition ด้วยคีย์ใด

⇨ จะสร้าง shard กี่ตัว และควรจัดโครงสร้างอย่างไร

→ การตัดสินใจ #1

⇨ Notion มี data model ที่ประกอบขึ้นในระดับ block

⇨ ตัดสินใจ shard ทุกตารางที่เชื่อมกับตาราง block (เช่น Space, Discussion, Comment เป็นต้น)

→ การตัดสินใจ #2

⇨ block ถูก partition ตาม workspace ID

⇨ แต่ละ workspace มี UUID กำกับอยู่แล้ว จึงนำมาใช้

→ การตัดสินใจ #3

⇨ จัดโครงสร้างด้วย 480 logical shards และ 32 physical DB

เหตุผลที่เลือก 480 แทน 512 ซึ่งเป็นเลขยกกำลังของ 2 คือเป็นตัวเลขที่แบ่งย่อยได้ยืดหยุ่นกว่า

  • ย้ายไปยัง shard

→ 1. เขียนข้อมูลซ้ำไปยัง Old & New DB ทั้งคู่ (พร้อม Audit Log)

→ 2. หลังเริ่ม dual-write แล้ว จึงเริ่ม backfill ข้อมูลจาก Old DB ไปยัง New DB

→ 3. ตรวจสอบความถูกต้องของข้อมูลใน New DB

→ 4. สลับไปใช้ New DB (ทำแบบ incremental)

  • บทเรียนที่ได้มาอย่างยากลำบาก

→ ทำ sharding ให้เร็วกว่านี้: เพราะรอจนภาระของ DB เดิมสูงมาก การ migration เองก็กลายเป็นภาระเพิ่ม จึงทำได้อย่างช้าๆ เท่านั้น

→ ตั้งเป้า migration แบบ zero downtime: throughput ของการทำ dual-write เป็นคอขวดสำคัญในช่วงสลับระบบสุดท้าย

→ ใช้ composite PK แทน partition key แยกต่างหาก: หากนำ id ซึ่งเป็น PK ของ DB เดิมมารวมกับ space_id ซึ่งเป็น partition key ก็อาจไม่จำเป็นต้องส่ง space_id ไปมาภายในแอป

1 ความคิดเห็น

 
xguru 2021-10-18

เรื่องของ TXID ใน Postgres เป็นหัวข้อที่ถูกพูดถึงอยู่เสมอ