TigerBeetle คือฐานข้อมูลที่น่าสนใจที่สุดในโลก
(amplifypartners.com)- ฐานข้อมูลธุรกรรมการเงิน TigerBeetle เป็นฐานข้อมูลรูปแบบใหม่ที่รองรับ เดบิต (debit) และ เครดิต (credit) แบบเนทีฟ โดยต่างจากฐานข้อมูล SQL แบบเดิมที่ต้องใช้ 10~20 คิวรีต่อธุรกรรมหนึ่งรายการ มันสามารถประมวลผล ธุรกรรม 8,190 รายการได้ในรอบการสื่อสารเดียว
- ขณะที่หลายระบบเลือกเขียนโค้ดให้เร็วและขยายการพึ่งพาไลบรารี โปรเจ็กต์นี้กลับยึดแนวทางสวนกระแสอย่าง เขียนโค้ดอย่างช้าๆ, Deterministic Simulation Testing (DST) และ zero dependency
- ต่างจากฐานข้อมูล OLTP เดิมที่พึ่งพาสถาปัตยกรรมโหนดเดียว โดยฝังแนวคิด กระจายแบบเป็นค่าเริ่มต้น, ทนต่อความขัดข้องของนาฬิกา (cluster time) และ ทนต่อความขัดข้องของสตอเรจ ไว้ในงานออกแบบ พร้อมใช้ Viewstamped Replication และ Zig เพื่อให้การพัฒนาเรียบง่ายและมองเห็นพฤติกรรมระบบได้ชัดเจน
- ใช้ แนวทาง TigerStyle ที่ได้แรงบันดาลใจจาก Power of Ten ของ NASA โดยยึดมาตรฐานการเขียนโค้ดอย่างเข้มงวด เช่น ใช้ assertion เฉลี่ยมากกว่า 2 จุดต่อฟังก์ชัน บังคับจัดสรรหน่วยความจำแบบสถิต และเปิด assertion แม้ในสภาพแวดล้อม production
- ด้วยโครงสร้างที่เหมาะกับยุค ธุรกรรมหนาแน่นสูงเป็นพิเศษ เช่น การชำระเงินแบบเรียลไทม์ เกมมิง และการคิดค่าพลังงานแบบเรียลไทม์ จึงกำลังก้าวขึ้นมาเป็นระบบประมวลผลธุรกรรมรุ่นถัดไปที่กำหนดมาตรฐานใหม่ด้าน ประสิทธิภาพและความถูกต้อง ของ OLTP และอาจ แทนที่ฐานข้อมูล SQL อายุ 20~30 ปี ที่ใช้อยู่ในปัจจุบัน
ความจำเป็นของฐานข้อมูลที่ยึดเดบิต/เครดิตเป็นศูนย์กลาง
- TigerBeetle เป็น "ฐานข้อมูลธุรกรรมการเงิน" ที่ใช้ เดบิต (debit) และเครดิต (credit) เป็น primitive หลัก
- แก่นแท้ของทรานแซกชันที่ Jim Gray ให้นิยามไว้ในปี 1985 ไม่ใช่ SQL transaction แต่คือ business transaction (เดบิต/เครดิต)
- แม้ผ่านไป 20 ปี Gray ก็ยังนิยามการประมวลผลธุรกรรมมาตรฐานว่าเป็น "DebitCredit": ทำเดบิตจากบัญชีธนาคาร ทำบัญชีคู่ แล้วจึงตอบกลับไปยังเทอร์มินัล
- เดบิต/เครดิตไม่ใช่สิ่งที่มีไว้เพื่อการบัญชีหรือธนาคารเท่านั้น แต่เป็น ภาษากลางที่สะท้อนแก่นของธุรกรรม และเป็นเหตุผลที่สามารถให้การรับประกันแบบ ACID ได้
- ปัญหาเมื่อพยายามทำเดบิต/เครดิตด้วยฐานข้อมูล SQL แบบเดิม
- การประมวลผลเดบิต/เครดิตหนึ่งครั้งต้องใช้ SQL คิวรี 10~20 ครั้ง เช่น อ่านยอดคงเหลือบัญชี ล็อกแถว รอการตัดสินใจในโค้ด แล้วค่อยบันทึกเดบิต/เครดิต
- ต้องถือ row lock ไว้ตลอดช่วงเวลา network round-trip และยิ่งทำให้ปัญหา hot row แย่ลงเมื่อมีธุรกรรมจำนวนมากเข้าถึง "house account" เดียวกัน
- จากการชำระเงินทันทีระดับหลายหมื่นล้านรายการต่อเดือนในอินเดียและบราซิล ไปจนถึง FedNow ของสหรัฐฯ และการคิดค่าบริการแบบเรียลไทม์ในพลังงาน เกม และคลาวด์ ทำให้โลกกำลัง มีความเป็น transaction-centric มากขึ้นอย่างน้อยระดับสามหลักภายใน 10 ปี ขณะที่ฐานข้อมูล SQL ที่ใช้กันอยู่ยังเป็นเทคโนโลยีเมื่อ 20~30 ปีก่อน
- จุดแตกต่างของ TigerBeetle
- ออกแบบเดบิต/เครดิตให้เป็น primitive ระดับเฟิร์สต์คลาส จึงประมวลผลธุรกรรม 8,190 รายการได้ในคิวรี 1MiB เพียงครั้งเดียวภายในการสื่อสารรอบเดียว
- ผู้ก่อตั้ง Joran เรียกสิ่งนี้ว่าเป็น "ไอเดียประสิทธิภาพระดับ 1000x" แต่ก็บอกว่า "ไม่ได้พิเศษอะไร"
- โดยทั่วไปฐานข้อมูลต้องใช้เวลาสร้าง 10 ปี แต่ TigerBeetle สร้างเสร็จใน 3.5 ปี และผ่านการทดสอบ Jepsen
- ในเดือนมิถุนายน 2025 Kyle Kingsbury ไม่สามารถทำลายรากฐานของ TigerBeetle ได้ แม้จะทำให้ตำแหน่งต่างๆ บนทุกเครื่องเสียหายหลายรูปแบบก็ตาม (พบเพียงบั๊กด้านความถูกต้อง 1 จุดในเอนจินคิวรีสำหรับการอ่านซึ่งไม่กระทบความทนทาน)
การออกแบบฐานข้อมูลสมัยใหม่
สถาปัตยกรรมแบบกระจายเป็นค่าเริ่มต้น
- ในยุคที่ Postgres และ MySQL ถูกสร้างขึ้น แนวคิด โหนดเดียว เป็นกระแสหลัก แต่ในยุคฮาร์ดแวร์คลาวด์แบบใช้ร่วมกันปัจจุบัน แนวคิด แบบกระจาย กลายเป็นกระแสหลัก
- ฐานข้อมูลสมัยใหม่จำเป็นต้องให้ serializability ที่เข้มงวด และทำสำเนาทรานแซกชันข้ามเครื่องเพื่อให้มีความซ้ำซ้อน ความทนทานต่อความขัดข้อง และความพร้อมใช้งานสูง
- ฐานข้อมูล OLTP ที่ได้รับความนิยมมากที่สุดบางตัวยังคงพึ่งพาสถาปัตยกรรมโหนดเดียวอย่างมาก และในบางกรณีก็ไม่มี automatic failover ติดตั้งมาเป็นค่าเริ่มต้น
- การออกแบบแบบกระจายของ TigerBeetle
- ถูกสร้างให้ กระจายแบบเป็นค่าเริ่มต้น เพียงติดตั้งไบนารีลงบนจำนวนเครื่องที่ต้องการในคลัสเตอร์
- ไม่ต้องพึ่ง asynchronous replication, Zookeeper ฯลฯ และลงทุนพัฒนา implementation ของโปรโตคอลฉันทามติ Viewstamped Replication จาก MIT โดยตรง
- นอกจาก Zig toolchain แล้ว ยังรักษาหลัก zero dependency และลงทุนพัฒนา dependency แกนหลักทั้งหมดด้วยตัวเอง
ความทนทานต่อความขัดข้องของนาฬิกา
- TigerBeetle เป็นฐานข้อมูลธุรกรรม จึงให้ความสำคัญกับ ความถูกต้องของ physical timestamp เพื่อการตรวจสอบย้อนหลังและการกำกับดูแล
- Linux มีนาฬิกาหลายแบบ เช่น
CLOCK_MONOTONIC_RAW,CLOCK_MONOTONIC,CLOCK_BOOTTIME - ด้วยข้อจำกัดทางกายภาพของฮาร์ดแวร์ นาฬิกาอาจเดินด้วยความเร็วต่างกันจนเกิดข้อผิดพลาดแบบ "drift" และสะสมเป็นข้อผิดพลาดแบบ "skew" ในช่วงเวลาสั้นๆ
- ปกติ NTP จะช่วยแก้ข้อผิดพลาดเหล่านี้ แต่หาก NTP หยุดทำงานแบบเงียบๆ จากปัญหาเครือข่ายบางส่วน คลัสเตอร์ฉันทามติที่มี high availability ก็อาจทำงานต่อไปโดยไม่มีใครรู้ตัว
- Linux มีนาฬิกาหลายแบบ เช่น
- การทำงานของ cluster time
- สร้าง "cluster time" ซึ่งเป็นนาฬิกาที่ทนต่อความขัดข้อง โดย รวมเสียงข้างมากของนาฬิกาในคลัสเตอร์
- หากจำเป็น จะปรับเวลา system time ของเซิร์ฟเวอร์ใหม่ หรือปิดการทำงานอย่างปลอดภัยหากมีนาฬิกาที่ผิดปกติมากเกินไป
- ตรวจจับได้จริงเมื่อ Chrony, PTP, NTP หยุดทำงาน และแจ้งเตือนผู้ปฏิบัติงาน
- ติดตามและสุ่มเก็บค่าเวลาที่เหลื่อมกันระหว่างเซิร์ฟเวอร์ แล้วใช้ Marzullo algorithm เพื่อประเมินช่วงเวลาที่แม่นยำที่สุด
การจัดการความขัดข้องของสตอเรจ
-
สมมติฐานของฐานข้อมูลแบบเดิม
- สมมติว่าเมื่อดิสก์เสีย ระบบจะล้มเหลวแบบคาดการณ์ได้พร้อมข้อความผิดพลาด
- เอกสารของ SQLite ระบุว่า: "SQLite ไม่ได้เพิ่มความซ้ำซ้อนให้ไฟล์ฐานข้อมูลเพื่อตรวจจับความเสียหายหรือ I/O error และสมมติว่าข้อมูลที่อ่านกลับมาจะตรงกับข้อมูลที่เคยเขียนไว้ทุกประการ"
-
สถานการณ์ความขัดข้องของสตอเรจในโลกจริง
- ดิสก์อาจคืนข้อมูลที่เสียหายแบบเงียบๆ ส่งต่อ I/O ไปผิดทิศทาง (เส้นทางอ่าน/เขียน) หรือช้าลงอย่างฉับพลันโดยไม่มี error code ซึ่งเป็น gray failure ได้
-
ความทนทานต่อความขัดข้องของสตอเรจใน TigerBeetle
- ใช้ Protocol Aware Recovery เพื่อคงความพร้อมใช้งานไว้ได้ ตราบใดที่สำเนาข้อมูลบนทุก replica ไม่เสียหายพร้อมกัน
- ข้อมูลทั้งหมดเป็น immutable และมี checksum กับ hash chain ที่ให้การรับประกันอย่างเข้มแข็งว่าไม่มีความเสียหายหรือการปลอมแปลง
- มี page cache ของตัวเอง เขียนข้อมูลลงดิสก์ด้วย O_DIRECT และสามารถรันบน raw block device ได้โดยตรง (ไม่ต้องใช้ filesystem) เพื่อ ลดจำนวนเลเยอร์ระหว่างดิสก์กับซอฟต์แวร์ให้น้อยที่สุด
- ใช้ LSM Forest ที่พัฒนาขึ้นเอง (ประมาณ 20 LSM tree) แทน LSM สำเร็จรูป
- ไม่เพียงอ้างว่าทนต่อความขัดข้องของสตอเรจ แต่ยังเป็นฐานข้อมูลแบบกระจายเพียงตัวเดียวที่ได้รับการตรวจสอบโดย Jepsen ในเรื่องนี้
- เมื่อเครื่องภายในล้มเหลว แม้จะเป็นเพียง sector บนดิสก์เสีย เอนจินสตอเรจก็ยังเชื่อมกับฉันทามติระดับ global เพื่อให้คลัสเตอร์เยียวยาตัวเองได้
เหตุผลที่เลือกภาษา Zig
-
ภาษาที่ฐานข้อมูลเดิมนิยมใช้
- Postgres เขียนด้วย C (ยุค 1970), MySQL ใช้ C และ C++ (1979) และ MSSQL ก็เขียนด้วย C และ C++ เช่นกัน
- ภาษาการเขียนโปรแกรมพัฒนาไปมากในช่วง 40 ปีที่ผ่านมา และหากสร้างใหม่ในวันนี้ ก็สามารถเลือก Rust หรือ Zig ได้
-
เหตุผลที่ TigerBeetle เลือก Zig
- ใช้งาน ecosystem ของ C ได้ทั้งหมด พร้อม toolchain และ compiler ที่ยอดเยี่ยม
- เขียนง่าย และโดยเฉพาะ อ่านง่าย บางกรณีง่ายพอๆ กับ TypeScript แต่เร็วกว่าอย่างมาก
- รองรับ การจัดสรรหน่วยความจำแบบสถิต ซึ่งเป็นหลักการสำคัญของ TigerBeetle
- มอบประสบการณ์นักพัฒนาที่ดี เรียนรู้ได้รวดเร็ว (จึงเข้ามาอ่านซอร์สโค้ด TigerBeetle ได้เร็ว)
- มีอดีตสมาชิกทีม Rust ช่วงแรกอย่าง Matklad (ผู้สร้าง Rust Analyzer) และ Brian Anderson (ผู้ร่วมก่อตั้ง Rust กับ Graydon) ทำงานอยู่ที่ TigerBeetle
- หากจะไม่ใช้ dynamic memory allocation ใน Rust จะเป็น "hard mode" แต่ใน Zig ทำได้ง่าย
Deterministic Simulation Testing และ VOPR
แนวคิดพื้นฐานของ DST
-
Deterministic Simulation Testing (DST) เป็นเทคนิคการทดสอบเชิงนวัตกรรมที่ทีม FoundationDB (ปัจจุบันเป็นของ Apple) ทำให้เป็นที่รู้จักอย่างแพร่หลาย
- ใช้เพื่อพัฒนาฐานข้อมูลแบบกระจายที่ปลอดภัยกว่าและมีบั๊กน้อยกว่าเดิมภายในเวลาที่สั้นลง
- ระบบแบบกระจายมีชุดปัญหาความพร้อมกันที่เป็นไปได้ไม่สิ้นสุด เช่น การสูญหายของข้อความ ลำดับการรันของเธรดที่คาดเดาไม่ได้ ฯลฯ
- การทดสอบแบบ unit test และ integration test แบบเดิมจึงไม่เพียงพอ ขณะที่ formal verification ก็มีต้นทุนสูงและช้า
-
หลักการทำงานของ DST
- เป็น ซิมูเลเตอร์ที่รันสถานการณ์ได้แทบทุกแบบอย่างเป็นเชิงกำหนด ที่ระบบอาจเผชิญในไทม์ไลน์หนึ่งๆ
- คำนึงถึงปัจจัยภายนอกอย่าง OS, เครือข่าย, ปัญหาดิสก์ หรือความหน่วงหลายรูปแบบด้วย
- ให้การทดสอบเทียบเท่าหลายปีภายในเวลาสั้นๆ (เพราะแม้แต่เวลาก็ถูกทำให้เป็นเชิงกำหนด จึงทำ while true loop ได้)
- เหมาะอย่างยิ่งกับฐานข้อมูล (เน้น I/O มากกว่า compute)
- การทดสอบ Jepsen เป็นเพียง ส่วนย่อยของสิ่งที่ DST ทำได้
VOPR ของ TigerBeetle
-
ภาพรวมของ VOPR (Viewstamped Operation Replicator)
- เป็นคลัสเตอร์ทดสอบที่พัฒนาขึ้นเอง ตั้งชื่อตามซิมูเลเตอร์ WOPR จากภาพยนตร์ WarGames
- ทดสอบ TigerBeetle อย่างต่อเนื่องภายใต้เงื่อนไขที่แตกต่างนับไม่ถ้วน ตั้งแต่วิธีที่โหนดเลือกผู้นำ ไปจนถึงความขัดข้องของ state และเครือข่ายแต่ละแบบ
- สามารถ จำลองคลัสเตอร์แบบกระจายทั้งชุดเสมือนจริงภายใน single thread ได้
-
ขนาดของ VOPR
- เป็น คลัสเตอร์ DST ที่ใหญ่ที่สุดในโลก รันบน CPU 1,000 คอร์
- ใหญ่ผิดปกติถึงขั้น Hetzner ต้องส่งอีเมลมาถามเป็นพิเศษว่าต้องการคอร์จำนวนมากขนาดนั้นจริงหรือไม่
- VOPR-1000 ทำงาน 24x7x365 เพื่อจับเงื่อนไขหายากให้ได้มากที่สุดก่อนขึ้น production
- ในซิมูเลเตอร์ เวลาเป็นนามธรรมแบบเชิงกำหนดและเร่งได้ราว 700 เท่า ทำให้สะสม simulation runtime ได้ราว 2,000 ปีต่อวัน
การทำ DST ให้เป็นเกม
- TigerBeetle เปลี่ยน DST ให้เป็น เกม ที่ให้เล่นสถานการณ์ความขัดข้องหลากหลายรูปแบบผ่านการตอบสนองของระบบ
- สามารถเล่นเกมได้ที่ sim.tigerbeetle.com
- รันอินสแตนซ์ VOPR จริงในเบราว์เซอร์เพื่อจำลอง TigerBeetle
- คอมไพล์เป็น WebAssembly และสร้างเกม frontend ขึ้นเพื่อให้วิศวกร TigerBeetle ใช้แสดงภาพของระบบจริง
TigerStyle และ Power of Ten
แนวทาง TigerStyle
-
TigerStyle คือ แนวทางวิศวกรรม ของ TigerBeetle และเปิดเผยไว้บน GitHub
- "การแลกเปลี่ยนร่วมกันที่พัฒนาอยู่เสมอ ณ จุดตัดระหว่างวิศวกรรมกับศิลปะ ตัวเลขกับสัญชาตญาณของมนุษย์ เหตุผลกับประสบการณ์ หลักการปฐมฐานกับความรู้ ความแม่นยำกับบทกวี"
- นำแนวคิด "Biodigital Jazz" จากภาพยนตร์ Tron: Legacy มาใช้: ความพัวพันของมนุษย์กับองค์ประกอบดิจิทัล ลักษณะที่ทั้งโกลาหลและมีโครงสร้างของ "Grid" และการแสดงออกถึงจิตวิญญาณการด้นสดของศักยภาพมนุษย์ภายในเทคโนโลยี
- สำหรับ TigerBeetle นี่คือจิตวิญญาณของโค้ดที่ใส่ศิลปะลงไปพร้อมกับวิทยาศาสตร์
-
อิทธิพลของ TigerStyle
- เสนอหลักการด้านวิศวกรรมและโค้ดที่ต่อยอดจาก Power of Ten ซึ่งเป็นหลักการเขียนโค้ดที่สมบูรณ์แบบของ NASA
- ครอบคลุมตั้งแต่หัวข้ออย่างความเรียบง่ายและความสง่างาม ไปจนถึงการประยุกต์ใช้ เช่น วิธีการตั้งชื่อ
- เริ่มส่งอิทธิพลไปยังบริษัทอื่นอย่าง Resonate และ Turso
- ยังถูกพูดถึงในพอดแคสต์ของ Lex Fridman ด้วย
การใช้ assertion
-
กฎข้อ 5 ของ Power of Ten: Assertion
- คือแนวคิดของการเขียนความคาดหวังต่อพฤติกรรมของโค้ด พร้อมกับ เข้ารหัสสิ่งนั้นอย่างชัดเจน ไม่ใช่ทำภายหลัง
- เขียนเป็นบูลีนในบรรทัดเดียว เช่น assert(a > b)
-
กฎ assertion ของ TigerStyle
- assert อาร์กิวเมนต์ของฟังก์ชัน ค่าที่คืนกลับ precondition และ invariant ทั้งหมด โดยมี assertion อย่างน้อยเฉลี่ย 2 จุดต่อฟังก์ชัน
- หาก assertion มีความสำคัญและชวนประหลาดใจ ให้ใช้ assertion แทนคอมเมนต์
- assert ความสัมพันธ์ระหว่างค่าคงที่ ณ compile time เพื่อตรวจสอบความสมบูรณ์ของการออกแบบก่อนโปรแกรมเริ่มทำงาน
- ไม่เพียง assert สิ่งที่ควรเกิดขึ้น แต่ยัง assert พื้นที่ด้านลบ ที่ไม่คาดว่าจะเกิดขึ้นด้วย (ซึ่งมักเป็นจุดที่บั๊กน่าสนใจโผล่มา)
วิธีคิดเรื่องประสิทธิภาพ
-
การให้เหตุผลและการออกแบบโค้ด สำคัญกว่าการเขียนโค้ดเสียอีก
- ช่วงเวลาที่ดีที่สุดในการแก้ปัญหาประสิทธิภาพและคว้าชัยชนะแบบ 1000x คือ ช่วงออกแบบ ซึ่งเป็นช่วงเวลาที่แม่นยำแต่ยังไม่สามารถวัดหรือทำ profiling ได้
-
หลักการด้านประสิทธิภาพของ TigerStyle
- ทำคณิตศาสตร์คร่าวๆ แบบเขียนบนกระดาษกับ "สี่สีพื้นฐาน" (เครือข่าย, สตอเรจ, หน่วยความจำ, CPU) และ "สองพื้นผิว" (แบนด์วิดท์และความหน่วง)
- แยก control plane ออกจาก data plane, ทำ access batching, แยก hot loop ออกเป็นฟังก์ชันเดี่ยวเพื่อลดการพึ่งพาคอมไพเลอร์ เป็นต้น
ลองใช้งานด้วยตัวเอง
- TigerBeetle นำงานวิจัยสมัยใหม่มาปรับใช้กับรูปแบบเดิม เพื่อมอบ การรับประกันด้านประสิทธิภาพและเสถียรภาพ ที่ไม่เคยมีมาก่อน
- เป็น เอนจิน OLTP สมัยใหม่ ที่ผสาน การโมเดลเดบิต/เครดิตแบบเนทีฟ, การกระจายเป็นค่าเริ่มต้น, ความทนทานต่อความขัดข้องของสตอเรจและนาฬิกา และ การประกันคุณภาพด้วย DST
- พัฒนางานวิศวกรรมระบบและสตอเรจให้เป็นเหมือนศิลปะรูปแบบหนึ่ง และไม่ลืมความสนุกระหว่างทาง
- ด้วย การใช้ DST อย่างชาญฉลาด จึงสร้างระบบให้ได้ตามมาตรฐาน Jepsen ภายในเวลาเพียงไม่กี่ปี
- การติดตั้งทำได้ง่ายด้วย ไบนารีเดียว และเริ่มต้นทดลองได้อย่างรวดเร็วผ่าน สคริปต์ติดตั้งแบบง่าย บนเว็บไซต์ทางการด้วยคำสั่ง curl เพียงไม่กี่คำ
6 ความคิดเห็น
ถ้าคิดดูว่าทำไม db ถึงไม่ใช้โหนดแบบกระจาย ก็จะเข้าใจได้ว่าทำไม postgres ถึงเป็นโหนดเดี่ยว
ลองคิดดูว่าอะไรสำคัญกว่าประสิทธิภาพ
ความคิดเห็นบน Hacker News
TigerBeetle นั้นยอดเยี่ยมก็จริง แต่อยากให้รู้ไว้ว่าบทความนี้เขียนโดยบริษัทลงทุนที่ลงทุนใน TigerBeetle ลิงก์ที่เกี่ยวข้อง
ในอีกไม่กี่เดือนข้างหน้า โพสต์แบบนี้ที่ฉันเขียนน่าจะออกมาเรื่อย ๆ หวังว่าคนจะมาถกกันมากขึ้น เลยสงสัยว่าควรเพิ่ม disclaimer ไว้ด้านบนจะดีกว่าไหม ซึ่งก็ไม่ยากที่จะเพิ่ม
บทความนี้ถูกโพสต์บนเว็บของบริษัทลงทุนอย่างชัดเจนภายใต้ชื่อ “Portfolio Spotlight” ดังนั้นก็ควรปรับความคาดหวังให้เหมาะสม
จะไม่พูดถึงวิธีการเขียนของบทความนี้มากนัก แต่ดูออกได้ง่ายมากว่านี่คือบทความจากบริษัทลงทุน
ฉันเป็นแฟนของการยึดความถูกต้อง แนวปฏิบัติการเขียนโค้ด และทิศทางที่เฉพาะทางมากของ TigerBeetle แต่ก็อยากวิจารณ์บางจุดในโพสต์นี้
คำอธิบายเรื่อง multi-node ค่อนข้างชวนให้เข้าใจผิด ไม่ว่าเหล่าคนสาย cloud-native จะพูดอย่างไร แค่มี DB เดี่ยวที่จูนมาดีและ connection pooler ก็รองรับ QPS มหาศาลได้แล้ว ที่บริษัทเก่าของฉัน ตอนบำรุงรักษาเคยเผลอส่งทราฟฟิกทั้งหมดไปที่ MySQL 8 RDS instance เดียว แต่ก็ยังรับ 80~90K QPS ได้สบาย ๆ instance ก็ไม่ได้ใหญ่ สคีมา คิวรี และการจูน ProxySQL/MySQL ดีเท่านั้นเอง ช่วงพีคใช้ writer กับ read replica สองตัวก็ยังไหวที่ 120K QPS
ถ้าใช้ node-local NVMe บนเซิร์ฟเวอร์ ก็มักจะชนเพดาน CPU ก่อน
เรื่อง redundancy นั้น ถ้าเป็น RDBMS ที่ออกแบบมาสำหรับสภาพแวดล้อมเครือข่าย สุดท้ายทุกเจ้าก็มี failover และ hot standby อยู่แล้ว
ระบบ consensus ของ TigerBeetle นั้นฉลาดและไม่มี external dependency แต่ก็ไม่ได้พยายามจัดการ row ขนาดใหญ่ ถ้าประมวลผลธุรกรรมนับพันในแพ็กเก็ต 1MiB ครั้งเดียว ก็อาจทำสิ่งที่ RDBMS แบบดั้งเดิมทำไม่ได้ให้เป็นไปได้
คำวิจารณ์เหล่านี้ไม่ได้มีเจตนาจะลดทอนความสำเร็จของพวกเขา และฉันก็ยังประทับใจกับผลิตภัณฑ์นี้มาก
การชี้ข้อจำกัดของ consensus protocol นั่นแหละคือประเด็นหลัก TigerBeetle ตั้งใจแยกมาจัดการเฉพาะงานธุรกรรม ไม่ได้จะมาแทนที่ OLGP db ทั้งหมด ความตั้งใจคือให้ย้ายเฉพาะข้อมูลสำคัญมาไว้ใน transactional DB แยกต่างหาก แนวทางคล้ายกันนี้ก็เห็นได้ใน TurboPuffer
RDBMS สมัยใหม่เร็วพอจริง แต่ use case ของ TigerBeetle คือสภาพแวดล้อมที่มี contention สูงเป็นพิเศษ ในการทดสอบจริงเคยพิสูจน์แล้วว่าเมื่อหลายธุรกรรมแตะบัญชีเดียวกัน throughput ของทั้งคลัสเตอร์จะตกลงอย่างรุนแรง (อ้างอิง: คอมเมนต์ HN ที่เกี่ยวข้อง)
ฉันชอบงานของ Joran และทีมมาก ทั้งเรื่อง DST การทำความเข้าใจ distributed systems และ performance testing โดยเฉพาะความหมกมุ่นกับการลด dependency ให้น้อยที่สุดนั้นน่าประทับใจมาก (แน่นอนว่าอาจมอง OS เป็น dependency ได้เหมือนกัน)
แต่ฉันรู้สึกมาตลอดว่าพวกเขาปฏิบัติต่อ OLTP ทั่วไป (ที่ทีมเรียกว่า OLGP) แบบไม่ค่อยยุติธรรม เช่น เวลายกตัวอย่างธุรกรรม SQL ที่ประสิทธิภาพต่ำอย่างการใช้แค่ row lock ในธุรกรรมการเงิน แล้วอธิบายราวกับว่าโลกยังยึดการออกแบบ OLTP เมื่อ 50 ปีก่อน
ในหน้า performance อย่างเป็นทางการ การตั้งค่าให้ contention ต่ำสุดได้แค่ 1% เท่านั้น ฉันไม่คิดว่าที่อย่าง Stripe จะถือว่า OLTP DB ของตัวเองมี contention 1%
เราสามารถสร้างระบบที่คาดการณ์ contention ได้ จัดการกับมันอย่างสวยงาม และทำ throughput ธุรกรรมระดับสุดขีดได้ ระบบแบบนี้ช่วยปกป้อง DB จาก contention เพื่อให้ขยายต่อได้เรื่อย ๆ ในความเป็นจริง ตัวเลข throughput ของระบบชำระเงินขนาดใหญ่นั้นสูงกว่าการเปรียบเทียบ performance อย่างเป็นทางการมาก
เนื้อหาฝั่งการตลาดมักมองข้ามเรื่องนี้ และพูดเหมือนนักพัฒนาทุกคนแค่โยนธุรกรรมที่ออกแบบไม่ดีเข้าไป ทั้งที่จริงแล้วส่วนใหญ่เป็นวิศวกรที่ฉลาดกว่านั้นมาก ในวงการการชำระเงินยังมีตำแหน่งงานชื่อว่า 'payments engineer' ด้วยซ้ำ
TigerBeetle นั้นยอดเยี่ยม แต่รูปแบบการตลาดที่ชวนให้คนเข้าใจ OLTP อื่น ๆ ผิดทำให้ฉันรู้สึกไม่สบายใจ
ขอบคุณสำหรับคำชื่นชม
คุณบอกว่า OLTP DB ของ Stripe ไม่น่าจะมี contention 1% แต่ Stripe ใช้ MongoDB เป็นฐาน การเปรียบเทียบกับ RDBMS จึงเหมือนเอาแอปเปิลไปเทียบกับส้ม
เรื่องจะมอง underlying OS เป็น dependency ได้ไหม ฉันเคยทำงานกับระบบที่รันแบบ in-memory ทั้งหมดและยังคงอยู่ต่อได้ระหว่าง
kexecด้วยซ้ำ ในสถานการณ์ที่แม้แต่ syscalls ยังทำไม่ได้ OS ก็ถือเป็น dependency ได้เต็ม ๆอยากขอตัวอย่างของธุรกรรมแบบใช้ lock เทียบกับแนวทาง optimization ที่ตรวจเงื่อนไขตอน commit time ได้ไหม
เราเคยพิจารณา TigerBeetle แต่มีอุปสรรคดังนี้
เราใช้ Cloudflare Workers แต่แอปไคลเอนต์ของ TigerBeetle ยังไม่รองรับ ลิงก์ issue อาจใช้ได้ถ้าเป็น Cloudflare Containers แต่ workflow ของเรายึด Workers เป็นหลัก
ไม่มีฟีเจอร์ authentication ใช้ได้แค่การจำกัด IP ที่ฝั่งเซิร์ฟเวอร์ (เช่น VPS) แต่ในสภาพแวดล้อม serverless เราไม่มี fixed IP issue ที่เกี่ยวข้อง
วิธี authenticate IP ด้วย ECC key ผ่าน Wireguard ก็อาจเป็นทางออกได้
จริง ๆ แล้วในสภาพแวดล้อมอย่าง Cloudflare Workers หรือ AWS Lambda ถ้า worker 1000 ตัวเปิด connection ไป DB พร้อมกันทั้งหมดก็จะเกิดปัญหาอยู่ดี ปกติจึงมักแก้ด้วยการวาง proxy หรือ service layer ไว้หน้า DB เมื่อ proxy รู้วิธีเข้าถึง DB ก็ไม่ต้องกังวลเรื่อง auth มากนักใน private network
ถ้าคุยกับทีมโซลูชันของ TigerBeetle คุณอาจได้รับข้อเสนอเป็นวิธีแก้แบบปรับแต่งเอง เช่น authentication ระดับ logical ผ่านการเข้ารหัสแบบ end-to-end
เป็นเรื่องเหลือเชื่อที่ปี 2025 ยังมี DB ที่ไม่มี authentication ถ้าเป็น DB การเงิน อย่างน้อยก็ควรมีคำแนะนำบนเว็บไซต์ว่าจะเพิ่ม authentication proxy/layer อย่างไร ถ้าไม่ได้ใช้ HTTP (ซึ่งจากเอกสารก็ยังไม่ชัด) คนก็ย่อมสงสัยกันหมดว่าจะวาง authentication proxy โดยไม่มี HTTP ได้อย่างไร ในสภาพนั้นถ้าเอาไปเปิดออกสู่อินเทอร์เน็ตจะอันตรายมาก
มีคำถามว่า “ในช่วง 10 ปี ปริมาณธุรกรรมเพิ่มขึ้นมากกว่า 1000 เท่า แต่ DB ที่ใช้ยังเป็น SQL อายุ 20-30 ปี มันจะไหวหรือ?” ฉันคิดว่าไหวแน่นอน
ต่อให้เป็นซอฟต์แวร์อายุ 30 ปี มันก็ถูกอัปเดตต่อเนื่องและมีรากฐานที่ออกแบบมาอย่างแข็งแรงตั้งแต่แรก
ผมคือ Joran (TigerBeetle) สำหรับ workload ทั่วไปไม่มีปัญหา แต่ในงานประมวลผลธุรกรรมจะเกิดปัญหา SQL row lock เพราะ power law contention (ดู Amdahl's Law ประกอบ) เราได้ลง contention calculator ไว้บนหน้าเว็บเพื่อให้คำนวณเพดานประสิทธิภาพสูงสุดตามทฤษฎีได้ contetion calculator
แค่ดูว่า DNS ซึ่งประกาศใช้ตั้งแต่ปี 1983 ยังเป็นรากฐานของอินเทอร์เน็ตได้จนถึงทุกวันนี้ ก็เห็นได้ว่าถ้าพื้นฐานดี ระบบอายุมากกว่า 30 ปีก็ยังไปต่อได้สบาย SQL ดีพอสำหรับ workload ส่วนใหญ่มาก
ไม่ใช่ว่าเทคโนโลยีใหม่และดูเท่กว่าจะดีกว่าเทคโนโลยีเดิมที่ผ่านการใช้งานและพิสูจน์ตัวเองมาแล้วเสมอไป บางครั้งฉันรู้สึกว่าวิศวกรซอฟต์แวร์คือวิศวกรที่ ‘ความจำสั้น’ ที่สุดในอุตสาหกรรม
เวลาต้องจัดการ DB หลายสิบตัวด้วย distributed system ก็จำเป็นต้องใช้ distributed transaction (เช่น Sagas) จริง แต่ถ้าเป็นกรณีเครื่องเดียว relational DB ก็ยังยอดเยี่ยมอยู่ดี
เมื่อก่อนฮาร์ดแวร์ยังแรงไม่พอ แต่ตอนนี้เทคโนโลยีพัฒนาแล้ว เลยกลับทำงานได้เร็วและดีขึ้นกว่าเดิม
FoundationDB ก็มีจุดร่วมกับการพูดคุยเรื่อง TigerBeetle หลายอย่างมาก
การเขียนโค้ดที่ช้า DST ไม่มี dependency โดยพื้นฐานเป็นระบบ distributed สำหรับ production ใช้ optimistic locking ที่ทนต่อ clock skew ผ่านการทดสอบหนักหน่วงของ Jepsen และใช้ภาษาใหม่อย่าง Flow ในการทดสอบ ด้วย FDB ก็แก้ปัญหาคล้ายกันได้เกือบทั้งหมด และฉันคิดว่า TigerBeetle แค่อาจถูกปรับให้เหมาะกับ use case มากกว่า
เหตุผลเดียวที่ FDB ไม่เป็นที่นิยมคือยังไม่มีเลเยอร์ที่ทำมาดีพอ แม้จะมีบางคนกำลังพัฒนาเลเยอร์สำหรับ SQS, DynamoDB และ SQLite แยกกันอยู่ก็ตาม
เหตุผลจริงที่ FDB ไม่เป็นที่นิยมคือ Apple มันออกในปี 2013 และผู้คนชอบผลิตภัณฑ์นี้มากจนบริษัทถูกซื้อกิจการ หลังจากนั้นผู้ใช้เดิมก็ถูกปิดบริการกันหมด แม้ช่วงผูกขาดจะจบแล้ว ความเชื่อใจก็ยังไม่กลับมา
เรากำลังร่วมงานกับทีม FDB และกำลังเตรียมโพสต์เกี่ยวกับ DST อยู่ด้วย
ก็อดสงสัยไม่ได้ว่าหลังการซื้อกิจการแล้วมันเป็นอย่างไรต่อ
ฉันมองว่ามันคือ 'the one true database' อย่างแท้จริง
พอถามว่า “ทำไม hyperscaler ทุกเจ้าถึงไม่ใช้ FDB” แล้วลองค้นใน github ดู ก็พบว่าสุดท้ายมันไปอยู่ใต้ Apple นี่เอง
ช่วงหลังฉันลองนำสไตล์การพัฒนาของ TigerBeetle ไปใช้กับ Rust, Go และภาษาอื่น ๆ แล้ว อยากแนะนำอย่างแรงจริง ๆ
single entry point, dependency แทบเป็นศูนย์
รัน CI ในเครื่องโลคัลได้ พร้อมคำสั่งเดียวสำหรับ test/coverage/lint เป็นต้น
เริ่มสนใจการใส่ simulation ผ่านการทดสอบแบบ property/snapshot/swarm
แยกเร็ว/ช้า ทุกเทสต์ใช้ seed เพื่อให้ deterministic
มี upper bound ที่ชัดเจน + ใช้ resource pool ทำให้แม้มี dynamic allocation โค้ดก็ยังเข้าใจง่ายขึ้น
ทั้งหมดนี้เพราะวิดีโอและเอกสารของทีม TB
ประโยคที่ว่า “เปิด assertion ไว้ใน production” น่าประทับใจมาก
ฉันไม่เคยเข้าใจเลยว่าทำไมถึงปิด assertion กันมาโดยตลอด ถ้า assert ล้มเหลวใน production เราก็ควรรู้ทันทีสิ (เป็นคำพูดเชิงวาทศิลป์)
ในเชิงประวัติศาสตร์ การปิด assertion เคยช่วยเรื่องประสิทธิภาพได้จริง แต่ทุกวันนี้การเปรียบเทียบเพิ่มอีกไม่กี่ครั้งแทบไม่มีผลอะไรแล้ว
เดิมที assertion คือการตรวจเพื่อกันไม่ให้ developer ใช้ API ผิดวิธี ถ้าอยู่ในขั้นรับอินพุตจากผู้ใช้ การเปลี่ยนเป็น business logic ที่มีข้อความ error ที่เหมาะสมจะสมเหตุสมผลกว่า
บางครั้งก็อยากใช้ assertion กับสิ่งที่ตรวจได้ไม่ง่าย เช่น ตรวจว่าลิสต์ถูกเรียงลำดับแล้ว
จุดประสงค์ดั้งเดิมของ assertion คือการตรวจตอน compile/test time ถ้าจะใช้ใน prod ก็เปลี่ยนเป็น
ifได้ ต้องคิดด้วยว่า assert เป็นเพียง syntax sugar ที่สะดวกหรือไม่อยากให้ทีม TB เผยแพร่โมเดล double-entry ให้กว้างขึ้นในกรณีที่ไม่ใช่การเงินด้วย เช่น หุ้น ตั๋วคอนเสิร์ต ฯลฯ มันมีประโยชน์มาก API ก็ปรับปรุงเสร็จแล้ว ถึงเวลาบอกวิธีนำไปใช้ได้แล้ว
ฉันทำงานสาย analyst ใช้ SQL เยอะ แต่ไม่ใช่คนพัฒนาโค้ด เข้าใจภาพรวมและข้อดีด้านประสิทธิภาพอยู่พอสมควร แต่มีคำถามอยู่ a) โครงสร้างข้อมูลของ TigerBeetle หน้าตาจริง ๆ เป็นอย่างไร? ไม่น่าจะเป็นตารางแบบทั่วไป b) ถ้าใช้ SQL query ไม่ได้ แล้วจะใช้งานมันอย่างไร c) ถ้านำโมเดล double-entry ไปใช้กับหุ้นหรือตั๋ว จะออกมาเป็นแบบไหน? เช่น ถ้าสถานที่จัดงานมีตั๋ว 1000 ใบและขายไปหนึ่งใบ จะลงบัญชีจาก inventory ไปเป็นเงินสด และจากรายได้รับล่วงหน้าไปเป็นภาระผูกพันในการให้บริการหรือไม่? หรือก่อนขายตั๋วจะยังไม่มี entry ใด ๆ เลย
ใน Postgres ก็สามารถทำ double-entry แบบคล้ายกันได้
คำพูดที่ว่า “ทีมส่วนใหญ่มักเขียนโค้ดให้เร็ว การทดสอบเป็นภาระ และกอง dependency ไว้เต็มไปหมด” จริง ๆ แล้วเมื่อ 25 ปีก่อนกลับเป็นมาตรฐานเสียมากกว่า ก่อนที่ Google และ Facebook จะนำวัฒนธรรม “move fast and break things” เข้ามา ทุกคนล้วนสร้างของอย่างรอบคอบ ช้า และทดสอบอย่างดี หวังว่า TigerBeetle จะได้รับการยอมรับมากขึ้น รายงานของ Jepsen ก็น่าอ่านมาก Jepsen report
รอดูไปอีก 25 ปีว่า TigerBeetle จะกลายเป็น Google หรือว่าผลิตภัณฑ์ที่ช้าแต่สมบูรณ์จะถูกคู่แข่งที่เร็วกว่าแย่งตลาดไป
“Move fast and break things” เป็นคำขวัญของ Facebook ส่วน Google กลับหมกมุ่นกับการทดสอบมากกว่า แน่นอนว่าต้องออกแบบให้ตรงกับความต้องการที่มีอยู่จริง และวิศวกรมักสร้างความต้องการสมมุติมากเกินไปจนไม่มีประสิทธิภาพ การส่งผลิตภัณฑ์ให้ผู้ใช้จริงเร็ว ๆ แล้วรับฟีดแบ็กกลับมาปรับปรุง มีค่ามากกว่าการขัดเกลาผลิตภัณฑ์ไม่รู้จบอยู่ใน ‘ฟองสบู่’
เนื้อหาของบทความข้างต้นก็ส่วนหนึ่ง แต่ตัวเว็บไซต์ของ TigerBeetle เองก็น่าประทับใจไม่น้อยเช่นกัน
ให้ความรู้สึกว่าอะไร ๆ ก็ดูเร็วมาก และดีไซน์ก็ดูพยายามถ่ายทอดเรื่องเทคนิคหนัก ๆ ให้ออกมาสนุกและเป็นกันเอง เลยรู้สึกว่าน่าสนใจดีครับ
ลิงก์: https://tigerbeetle.com
ขอแก้ไขครับ/ค่ะ พอกลับไปดูอีกทีก็รู้สึกว่ามันค่อนข้างหนักอยู่เหมือนกัน แต่ในแง่ความงามแล้วรู้สึกประทับใจมาก เลยอยากแชร์ :)
จริงนะ แอนิเมชันทำได้รวดเร็ว เลยสร้างหน้าจอที่ไม่น่าเบื่อโดยไม่รบกวนสมาธิกับเนื้อหา และยังสื่อเป็นนัยอย่างชัดเจนด้วยว่า TigerBeetle เร็วมาก 555
น่าสนใจมากเลยครับ
ตั้งเวลาแอนิเมชันไว้สั้นกว่าพวกเว็บไซต์ทั่วไปมากเลยนะครับ แบบนี้ก็สามารถคลี่ออกมาได้เหมือนกันแฮะ...