- Stripe ประมวลผลปริมาณการชำระเงินรวม 1 ล้านล้านดอลลาร์ในปี 2023 พร้อมรักษา uptime ที่ 99.999%
- ทีมโครงสร้างพื้นฐานฐานข้อมูลของ Stripe ให้บริการชั้นฐานรากของ API ในรูปแบบฐานข้อมูล as a service (DBaaS) ที่ชื่อว่า DocDB
- DocDB เป็น MongoDB Community เวอร์ชันที่ขยายเพิ่มเติม และประกอบด้วยบริการหลายตัวที่ Stripe สร้างขึ้นภายใน
- รองรับคิวรีมากกว่า 5 ล้านครั้งต่อวินาที และจัดเก็บข้อมูลการเงินสำคัญระดับเพตะไบต์โดยกระจายไปยังชาร์ดฐานข้อมูลมากกว่า 2,000 ชาร์ด และคอลเลกชันมากกว่า 5,000 ชุด
- เหตุผลที่เลือก MongoDB Community คือความยืดหยุ่นของ document model และความสามารถในการประมวลผลข้อมูลเรียลไทม์ในระดับใหญ่
- ในปี 2011 ยังไม่มี MongoDB Atlas จึงสร้างคลัสเตอร์ MongoDB instance แบบ self-managed ที่รันบนคลาวด์ขึ้นมาเอง
- หัวใจสำคัญของ DocDB คือ Data Movement Platform
- เดิมทีสร้างขึ้นเป็นโซลูชันสำหรับ scale แบบแนวนอนเพื่อก้าวข้ามข้อจำกัดของการ scale แบบแนวตั้งของ MongoDB แต่ต่อมาถูกปรับแต่งให้ใช้ได้กับหลายวัตถุประสงค์
- เช่น การรวมชาร์ดฐานข้อมูลที่ไม่ได้ใช้งานเพื่อเพิ่มการใช้งานและประสิทธิภาพ, การอัปเกรด major version ของ database engine เพื่อเพิ่มความเสถียร, และการย้ายจาก multi-tenant ไปเป็น single-tenant สำหรับผู้ใช้รายใหญ่
- Data Movement Platform ทำให้สามารถย้ายจากชาร์ดฐานข้อมูลขนาดใหญ่จำนวนน้อย ไปเป็นชาร์ดฐานข้อมูลขนาดเล็กจำนวนมากได้
- อีกทั้งยังรองรับการย้ายข้อมูลที่โปร่งใสต่อไคลเอนต์และไม่มีดาวน์ไทม์ ทำให้สามารถให้บริการ DBaaS ที่ยืดหยุ่นสูงได้
- DocDB สามารถแยกชาร์ดฐานข้อมูลเมื่อทราฟฟิกพุ่งสูง และเมื่อทราฟฟิกลดลงก็สามารถรวมฐานข้อมูลหลายพันตัวผ่าน bin packing ได้
วิธีสร้างโครงสร้างพื้นฐานฐานข้อมูล
- ตอนเปิดตัวในปี 2011 Stripe เลือก MongoDB เป็นฐานข้อมูลออนไลน์ เพราะช่วยเพิ่ม productivity ของนักพัฒนาได้ดีกว่าฐานข้อมูลเชิงสัมพันธ์มาตรฐาน
- Stripe ต้องการรันโครงสร้างพื้นฐานฐานข้อมูลที่แข็งแกร่งบน MongoDB โดยให้ความสำคัญกับเสถียรภาพของ API เป็นอันดับแรก แต่ไม่พบ DBaaS สำเร็จรูปที่ตอบโจทย์
- ต้องรองรับ availability, durability และ performance ระดับสูงสุด
- เปิดเผยฟีเจอร์ฐานข้อมูลให้น้อยที่สุด เพื่อป้องกันปัญหาที่เกิดจากคิวรีที่ไม่ได้รับการปรับแต่งจากแอปพลิเคชันลูกค้าเอง
- รองรับ horizontal scalability ผ่าน sharding
- รองรับ multi-tenancy พร้อม enforced quota ได้อย่างยอดเยี่ยม
- มีความปลอดภัยสูงผ่านการบังคับใช้นโยบาย authorization
- ทางออกคือการสร้าง DocDB โดยใช้ MongoDB เป็น storage engine พื้นฐาน ซึ่งเป็น DBaaS ที่ยืดหยุ่นและขยายขนาดได้อย่างแท้จริง โดยมี online data migration เป็นแกนหลัก
- แอปพลิเคชันผลิตภัณฑ์ของ Stripe เข้าถึงข้อมูลในฐานข้อมูลผ่านฝูง database proxy server ที่พัฒนาขึ้นภายในด้วย Go เพื่อบังคับใช้นโยบายด้าน reliability, scalability, admission control และ access control
- และได้ตัดสินใจเชิงสถาปัตยกรรมสำคัญให้ใช้ sharding เป็นกลไก horizontal scaling
- ปัจจุบันชาร์ดฐานข้อมูลหลายพันตัวที่แต่ละตัวเก็บข้อมูลสะสมเป็นชิ้นเล็ก ๆ ได้กลายเป็นรากฐานของทุกผลิตภัณฑ์ของ Stripe
- เมื่อแอปพลิเคชันส่งคิวรีไปยัง database proxy server ระบบจะ parse คิวรีและ route ไปยังหนึ่งชาร์ดหรือหลายชาร์ด จากนั้นรวมผลลัพธ์จากชาร์ดและส่งกลับไปยังแอปพลิเคชัน
- Database proxy server อาศัย chunk metadata service ในการแมปชังก์เข้ากับชาร์ดฐานข้อมูล ทำให้ค้นหาชาร์ดที่เกี่ยวข้องกับคิวรีที่กำหนดได้ง่าย
- event การเปลี่ยนแปลงจากการเขียนลงฐานข้อมูลจะถูกส่งไปยังระบบ streaming software และท้ายที่สุดถูกจัดเก็บใน object storage ผ่าน pipeline ของ change data capture (CDC)
- ทีมของ Stripe จัดเตรียม logical container ของข้อมูลที่เรียกว่า logical database ที่ระดับ product application โดยใช้ internal document database control plane ซึ่งประกอบด้วย DocDB collection หนึ่งชุดหรือมากกว่าที่มีวัตถุประสงค์เกี่ยวข้องกัน
- ข้อมูลของ DocDB collection เหล่านี้จะถูกกระจายไปยังหลายฐานข้อมูล (physical database) ที่เก็บชังก์ขนาดเล็กของคอลเลกชัน
- Physical database ของ DocDB อยู่บนชาร์ดที่ถูกดีพลอยเป็น replica set ซึ่งประกอบด้วย primary node และ secondary node หลายตัวพร้อมการ replication และ automatic failover
วิธีออกแบบ Data Movement Platform
- การสร้างผลิตภัณฑ์ DBaaS ที่ scale แบบแนวนอนได้และมีความยืดหยุ่นสูง ซึ่งสามารถขยายและหดตามความต้องการของ product application ได้ จำเป็นต้องมีความสามารถในการย้ายข้อมูลระหว่างชาร์ดฐานข้อมูลแบบไม่มีดาวน์ไทม์และโปร่งใสต่อไคลเอนต์
- นี่เป็นปัญหาระบบ distributed system ที่ซับซ้อน และยิ่งซับซ้อนขึ้นจากข้อกำหนดเฉพาะของข้อมูลการเงินสำคัญ
- ความสอดคล้องและความครบถ้วนของข้อมูล: ต้องรับประกันว่าข้อมูลที่กำลังย้ายจะคงความสอดคล้องและครบถ้วนทั้งบน source shard และ target shard
- ความพร้อมใช้งาน: ไม่สามารถยอมรับการหยุดทำงานเป็นเวลานานระหว่างการย้ายข้อมูลได้ เพราะธุรกิจหลายล้านรายพึ่งพา Stripe ในการรับชำระเงินจากลูกค้าตลอด 24 ชั่วโมง
- เป้าหมายคือให้ขั้นตอนหลักของกระบวนการย้ายข้อมูลสั้นกว่าเวลาที่ใช้ planned database primary failover ซึ่งปกติใช้เวลาเพียงไม่กี่วินาที และต้องอยู่ภายใน retry budget ของ product application
- ความละเอียดและความยืดหยุ่นในการปรับตัว: ที่สเกลของ Stripe ต้องสามารถย้ายชังก์ข้อมูลจำนวนเท่าใดก็ได้ จาก source จำนวนเท่าใดก็ได้ ไปยัง target shard จำนวนเท่าใดก็ได้
- ต้องไม่มีข้อจำกัดทั้งต่อจำนวนการย้าย database chunk ที่กำลังเกิดขึ้นพร้อมกันในฟลีต และต่อจำนวนการย้ายที่ชาร์ดใดชาร์ดหนึ่งจะเข้าร่วมได้ในช่วงเวลาใดช่วงเวลาหนึ่ง
- นอกจากนี้ เนื่องจากชาร์ดฐานข้อมูลจำนวนมากมีข้อมูลระดับเทราไบต์ จึงต้องย้ายชังก์หลากหลายขนาดด้วย throughput สูงได้
- ไม่มีผลกระทบด้านประสิทธิภาพต่อ source shard: ระหว่างการย้าย database chunk ข้ามชาร์ด เป้าหมายคือรักษา performance และ throughput ที่มีอยู่ของ source shard เพื่อไม่ให้กระทบเชิงลบต่อ performance และ throughput ที่พร้อมให้บริการสำหรับคิวรีของผู้ใช้
- เพื่อแก้โจทย์เหล่านี้ Stripe จึงสร้าง data movement platform ที่เรียกใช้บริการที่สร้างขึ้นเพื่อวัตถุประสงค์เฉพาะเพื่อจัดการ online data migration ระหว่างชาร์ดฐานข้อมูล
- คอมโพเนนต์ Coordinator ของ data movement platform รับหน้าที่ orchestration หลายขั้นตอนที่เกี่ยวข้องกับ online data migration โดยเรียกใช้บริการที่เกี่ยวข้องเพื่อดำเนินการแต่ละขั้นตามที่อธิบายด้านล่าง
ขั้นตอนที่ 1: ลงทะเบียนการย้ายชังก์
- เริ่มจากลงทะเบียนเจตนาที่จะย้าย database chunk จาก source shard ไปยัง target shard ใดก็ได้ ใน chunk metadata service
- หลังจากนั้นจึงสร้างดัชนีบน target shard สำหรับชังก์ที่กำลังย้าย
ขั้นตอนที่ 2: นำเข้าข้อมูลแบบจำนวนมาก
- จากนั้นใช้ snapshot ของชังก์บน source shard ณ เวลา T เพื่อโหลดข้อมูลไปยังชาร์ดฐานข้อมูลหนึ่งตัวหรือหลายตัว
- บริการที่ทำ bulk data import รองรับ data filter หลายรูปแบบ และจะนำเข้าเฉพาะชังก์ข้อมูลที่ตรงตามเกณฑ์การกรอง
- ตอนแรกดูเหมือนง่าย แต่กลับพบข้อจำกัดด้าน throughput เมื่อโหลดข้อมูลจำนวนมากเข้าสู่ DocDB shard
- แม้จะพยายาม batch การเขียนและปรับพารามิเตอร์ของ DocDB engine เพื่อให้เหมาะกับ bulk ingestion แล้ว ก็ยังไม่ค่อยประสบความสำเร็จ
- แต่เกิดความก้าวหน้าครั้งสำคัญเมื่ออาศัยข้อเท็จจริงที่ว่า DocDB ใช้โครงสร้างข้อมูล B-tree ในการจัดเรียงข้อมูล แล้วหาวิธีปรับลำดับการ insert ให้เหมาะสม
- ด้วยการจัดเรียงข้อมูลตามคุณสมบัติของดัชนีที่พบได้บ่อยที่สุดใน collection และ insert ตามลำดับที่จัดเรียงนั้น ทำให้ write locality ดีขึ้นอย่างมาก และเพิ่ม write throughput ได้ 10 เท่า
ขั้นตอนที่ 3: การจำลองข้อมูลแบบอะซิงโครนัส
- หลังจากนำเข้าข้อมูลไปยัง target shard แล้ว จะเริ่มจำลองการเขียนจาก source ไปยัง target shard สำหรับ database chunk ที่กำลังย้าย ตั้งแต่เวลา T เป็นต้นไป
- ระบบ asynchronous replication จะอ่านการเปลี่ยนแปลงที่เกิดจากการเขียนบน source shard จากระบบ CDC แล้วทำการเขียนไปยัง target shard
- operation log หรือ oplog คือคอลเลกชันพิเศษของแต่ละ DocDB shard ที่เก็บบันทึกของทุก operation ที่เปลี่ยนแปลงข้อมูลในฐานข้อมูลของชาร์ดนั้น
- oplog ของทุก DocDB shard จะถูกส่งไปยัง Kafka ซึ่งเป็น event streaming platform จากนั้นเก็บรักษาไว้ในบริการ cloud object storage เช่น Amazon S3
- Stripe จึงสร้างบริการที่ใช้ event จาก oplog ใน Kafka และ Amazon S3 เพื่อ replicate การเปลี่ยนแปลงจาก source DocDB shard หนึ่งตัวหรือหลายตัว ไปยัง target DocDB shard หนึ่งตัวหรือหลายตัว
- การพึ่งพา event จาก oplog ของระบบ CDC ทำให้ไม่ต้องใช้ read throughput ของ source shard ที่ควรสงวนไว้สำหรับคิวรีผู้ใช้ จึงไม่ทำให้ความเร็วของคิวรีผู้ใช้ช้าลง และไม่ถูกจำกัดด้วยขนาด oplog ของ source shard
- บริการนี้ยังถูกออกแบบให้ยืดหยุ่น แม้ในกรณีที่ target shard ไม่พร้อมใช้งาน และสามารถเริ่ม หยุดชั่วคราว และดำเนินการ sync ต่อจาก checkpoint ได้ทุกเมื่อ
- บริการ replication ยังมีความสามารถในการดึง replication lag มาใช้งานด้วย
- การเปลี่ยนแปลงของชังก์ที่กำลังย้ายจะถูก replicate แบบสองทิศทางจาก source shard ไปยัง target shard และย้อนกลับ และบริการ replication จะใส่แท็กให้กับการเขียนที่มันปล่อยออกไป เพื่อป้องกัน cyclic asynchronous replication
- นี่เป็นการเลือกออกแบบโดยตั้งใจ เพื่อให้มีความยืดหยุ่นในการสลับทราฟฟิกกลับไปยัง source shard ได้ หากเกิดปัญหาเมื่อส่งทราฟฟิกไปยัง target shard
ขั้นตอนที่ 4: ตรวจสอบความถูกต้อง
- เมื่อการ replication ระหว่าง source shard และ target shard ซิงก์กันแล้ว จะมีการเปรียบเทียบ snapshot ณ จุดเวลาเดียวกันเพื่อยืนยันความครบถ้วนและความถูกต้องของข้อมูลอย่างครอบคลุม
- นี่เป็นการตัดสินใจออกแบบโดยตั้งใจ เพื่อไม่ให้กระทบต่อ throughput ของชาร์ด
ขั้นตอนที่ 5: สลับทราฟฟิก
- เมื่อข้อมูลของชังก์ถูกนำเข้าจาก source ไปยัง target shard และมีการ replicate การเปลี่ยนแปลงอย่างต่อเนื่องแล้ว Coordinator จะทำ orchestration ของการสลับทราฟฟิก
- ในการเปลี่ยนเส้นทางการอ่านและการเขียนสำหรับ data chunk ที่กำลังย้าย จะต้องหยุดทราฟฟิกไปยัง source shard ชั่วคราวก่อน อัปเดตเส้นทางใน chunk metadata service และให้ proxy server redirect การอ่านและการเขียนไปยัง target shard
- โปรโตคอลการสลับทราฟฟิกอิงกับแนวคิดของ version gating
- ใน steady state แต่ละ proxy server จะเพิ่มหมายเลข version token ไปกับคำขอที่ส่งไปยัง DocDB shard
- Stripe เพิ่ม custom patch ให้กับ MongoDB เพื่อให้ชาร์ดสามารถตรวจสอบได้ว่าหมายเลข version token ของคำขอที่ได้รับจาก proxy server ใหม่กว่าหมายเลข version token ที่ตนเองรู้จักหรือไม่ และจะประมวลผลเฉพาะคำขอที่ผ่านเกณฑ์นี้
- ในการอัปเดตเส้นทางของชังก์ Coordinator จะดำเนินขั้นตอนดังต่อไปนี้:
- เริ่มจากเพิ่มหมายเลข version token ของ source DocDB shard ก่อน หมายเลข version token นี้ถูกเก็บไว้ในเอกสารในคอลเลกชันพิเศษของ DocDB และ ณ จุดนี้ การอ่านและการเขียนทั้งหมดสำหรับชังก์บน source shard จะถูกปฏิเสธ
- จากนั้นรอให้บริการ replication replicate การเขียนที่ค้างอยู่จาก source shard ให้เสร็จ
- สุดท้ายอัปเดตเส้นทางของชังก์ใน chunk metadata service ให้ชี้ไปยัง target shard และหมายเลข version token
- เมื่อเสร็จแล้ว proxy server จะดึงเส้นทางที่อัปเดตแล้วสำหรับชังก์และหมายเลข version token ล่าสุดจาก chunk metadata service
- Proxy server จะใช้เส้นทางที่อัปเดตแล้วของชังก์เพื่อ route การอ่านและการเขียนของชังก์ไปยัง target shard
- โปรโตคอลการสลับทราฟฟิกทั้งหมดใช้เวลาทำงานน้อยกว่า 2 วินาที และการอ่านหรือการเขียนที่ล้มเหลวทั้งหมดที่ถูกส่งไปยัง source shard จะสำเร็จเมื่อมีการ retry
ขั้นตอนที่ 6: ยกเลิกการลงทะเบียนการย้ายชังก์
- สุดท้าย จะทำเครื่องหมายการย้ายว่าเสร็จสมบูรณ์ใน chunk metadata service และลบข้อมูลชังก์ออกจาก source shard เพื่อปิดกระบวนการย้ายข้อมูล
การนำ Data Movement Platform ไปใช้งาน
- ความสามารถในการย้าย data chunk ระหว่าง DocDB shard แบบออนไลน์ ช่วยให้ Stripe ขยายโครงสร้างพื้นฐานฐานข้อมูลในแนวนอนให้ทันกับอัตราการเติบโตของบริษัทได้
- วิศวกรของทีมโครงสร้างพื้นฐานฐานข้อมูลสามารถแบ่ง DocDB shard ตามขนาดและ throughput ได้เพียงคลิกปุ่มเดียว เพื่อสร้างพื้นที่เผื่อด้าน storage และ throughput สำหรับทีมผลิตภัณฑ์
- ในปี 2023 Stripe ใช้ data movement platform เพื่อปรับปรุงการใช้ประโยชน์จากโครงสร้างพื้นฐานฐานข้อมูล
- โดยเฉพาะได้ย้ายข้อมูล 1.5 เพตะไบต์แบบโปร่งใสต่อ product application เพื่อทำ bin-pack ฐานข้อมูลที่ใช้ประโยชน์ต่ำหลายพันตัว และลดจำนวน DocDB shard พื้นฐานทั้งหมดลงเหลือประมาณสามในสี่
- นอกจากนี้ยังใช้ data movement platform เพื่ออัปเกรดฟลีตโครงสร้างพื้นฐานฐานข้อมูล โดย forklift ข้อมูลไปยัง MongoDB เวอร์ชันใหม่กว่าได้ในขั้นตอนเดียว โดยไม่ต้องผ่าน major/minor version ระหว่างทาง
- ทีมโครงสร้างพื้นฐานฐานข้อมูลของ Stripe ยังคงมุ่งเน้นการสร้างรากฐานที่แข็งแกร่งและเชื่อถือได้ ซึ่งขยายตามการเติบโตของเศรษฐกิจอินเทอร์เน็ต
- ปัจจุบันกำลังทำต้นแบบระบบ heat management ที่คอยปรับสมดุลข้อมูลระหว่างชาร์ดล่วงหน้าตามขนาดและ throughput และกำลังลงทุนใน autoscaling ของชาร์ดเพื่อรับมือกับการเปลี่ยนแปลงของรูปแบบทราฟฟิกแบบไดนามิก
ยังไม่มีความคิดเห็น