1 คะแนน โดย GN⁺ 2025-06-07 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • TigerBeetle เป็นฐานข้อมูล OLTP ที่ออกแบบมาเฉพาะสำหรับ ระบบบัญชีแบบเดบิต-เครดิตคู่ โดยพัฒนาขึ้นโดยมุ่งเน้น ความปลอดภัยและความเร็วในการประมวลผล
  • รองรับโปรโตคอลฉันทามติ Viewstamped Replication และเกณฑ์ strong serializability พร้อมโครงสร้างที่เหมาะกับงาน คอนเทนชันสูงและปริมาณงานสูง
  • มีการออกแบบและขั้นตอนทดสอบที่ให้ความสำคัญอย่างมากกับ ความทนทานต่อความขัดข้อง และการกู้คืนจากปัญหา โดยมุ่งให้ทำงานได้โดยไม่สูญเสียข้อมูลในสถานการณ์ขัดข้องหลากหลายรูปแบบ
  • การทดสอบของ Jepsen พบ บั๊กและปัญหาด้านประสิทธิภาพหลายประการ ในด้านการอัปเกรด การทดสอบ แบบจำลองการดำเนินการ และความทนทานของคลัสเตอร์ต่อความขัดข้อง ซึ่งช่วยให้สามารถปรับปรุงแนวทางรับมือได้
  • เวอร์ชันล่าสุดมีการปรับปรุงและแก้ไขบั๊กหลายด้าน เช่น ประสิทธิภาพการทำ replication แบบ Ring, การจัดการข้อผิดพลาดของไคลเอนต์, ความถูกต้องของ logging และ query

แนะนำ TigerBeetle

  • TigerBeetle เป็น ฐานข้อมูลสำหรับการประมวลผลธุรกรรมออนไลน์ (OLTP) ที่ออกแบบมาเฉพาะสำหรับ ระบบบัญชีแบบเดบิต-เครดิตคู่ (Double-entry bookkeeping)
  • รับประกัน strong serializability บนพื้นฐานโปรโตคอลฉันทามติ Viewstamped Replication(VR) และจัดเก็บเฉพาะข้อมูลบัญชีและการโอนระหว่างบัญชี
  • เหมาะกับสภาพแวดล้อมที่ มีปริมาณธุรกรรมสูงและมีการแข่งขันด้าน concurrency รุนแรง เช่น ระบบสวิตช์ภายในธนาคาร นายหน้า การออกตั๋ว และการวัดพลังงานไฟฟ้า
  • ใช้สถาปัตยกรรมที่ให้โหนดเดี่ยว (Core) ดูแลการเขียนทั้งหมด จึง มุ่งเน้นการขยายแบบ Scale-up มากกว่า Scale-out
  • ตั้งเป้าเพิ่ม throughput ของโหนดเดี่ยวให้สูงสุดผ่าน การประมวลผลแบบ batch, IO แบบขนาน, fixed schema และการเพิ่มประสิทธิภาพที่เป็นมิตรกับฮาร์ดแวร์

ความสามารถในการกู้คืนจากความขัดข้องและการทนต่อความผิดพลาด

  • TigerBeetle มีแบบจำลองและขั้นตอนกู้คืนอย่างชัดเจนสำหรับ ความผิดพลาดของหน่วยความจำ โปรเซส นาฬิกา สตอเรจ และเครือข่าย
  • ความทนทานของข้อมูลรับประกันว่า ตราบใดที่ยังเหลือ replica เพียงหนึ่งชุด ข้อมูลจะไม่สูญหาย
    • หากบันทึกของ replica ทั้งหมดเสียหาย ระบบจะหยุดอย่างปลอดภัย
  • สมมติให้เกิดความขัดข้องได้หลากหลาย เช่น ปัญหาฮาร์ดแวร์/ซอฟต์แวร์ของระบบ ความคลาดเคลื่อนของนาฬิกา ความเสียหายของดิสก์ ความหน่วงของเครือข่าย การสูญหาย และข้อมูลซ้ำ
  • ใช้ Viewstamped Replication, เทคนิค Protocol-Aware Recovery, checksum ของบล็อกข้อมูล และการจัดเก็บหลาย replica
  • ใช้ runtime verification (assertion) เพื่อลดผลกระทบเมื่อเกิดข้อผิดพลาดหรือบั๊ก

วิธีการอัปเกรด

  • ไบนารีมีทั้ง โค้ดของเวอร์ชันปัจจุบันและหลายเวอร์ชันก่อนหน้า รวมอยู่ด้วย
  • การอัปเกรดทำได้ง่ายเพียงแค่เปลี่ยนไบนารี
  • ทุกโหนดในคลัสเตอร์จะเปลี่ยนเวอร์ชันแบบ rolling โดยอัตโนมัติ ลดการแทรกแซงจากผู้ใช้ให้น้อยที่สุด
  • ป้องกันไม่ให้ operation ที่ commit ในเวอร์ชันหนึ่งถูก commit ซ้ำในอีกเวอร์ชันหนึ่ง จึงช่วย ป้องกันความไม่สอดคล้องของสถานะ

แบบจำลองเวลา

  • ใช้นาฬิกาเชิงตรรกะจาก VR view และหมายเลข operation ควบคู่กับ นาฬิกากายภาพแบบไฮบริด (physical time)
  • ผู้นำจะรวบรวมเวลา POSIX ของ replica ทั้งหมดและซิงก์กันภายในขอบเขตความคลาดเคลื่อนที่กำหนด
  • หากการซิงก์นาฬิกาล้มเหลวนานเกิน 60 วินาที ระบบจะปฏิเสธการให้บริการ
  • timestamp ใช้หน่วยเป็น "นาโนวินาทีนับจาก Unix epoch" แต่ คลาดจากเวลา POSIX จริง 27 วินาที
  • เมื่อมี leap second หรือการปรับเวลาย้อนกลับ นาฬิกาภายในอาจช้าลง

แบบจำลองข้อมูล

  • รองรับข้อมูลเพียงสองประเภทคือ account และ transfer
    • แต่ละฟิลด์มีขนาดคงที่ ยึดหลัก immutable และออกแบบบนพื้นฐาน unsigned int
  • account นิยามด้วย id แบบ 128 บิตที่ผู้ใช้กำหนดเอง, ledger, flags, เวลาสร้าง และ custom fields
  • transfer มี debit/credit account id, code, amount, custom fields ฯลฯ
  • transfer รองรับทั้งการทำทันที (ขั้นตอนเดียว) และการประมวลผลแบบ 2 ขั้นตอน (การจองและการยืนยันดำเนินการ)
    • การโอนแบบ pending สามารถยกเลิกหรือหมดอายุได้
    • สามารถใช้ transfer แบบพิเศษเพื่อปิดหรือเปิดบัญชีใหม่ได้

แบบจำลองการดำเนินการและทรานแซกชัน

  • ไคลเอนต์ทำงานเป็นหน่วย คำขอเดี่ยว (batch) สำหรับอัปเดตหรืออ่านสถานะข้อมูล
  • แต่ละเหตุการณ์ในคำขอจะถูกประมวลผลตามลำดับและเป็น ทรานแซกชันแบบอะตอมมิก (atomic)
  • ไม่รองรับการรันซ้ำ ทรานแซกชันหลายคำขอ หรือ interactive query
  • ให้ทั้ง Strong Serializability และ strong session consistency
  • รองรับผลลัพธ์สำเร็จ/ล้มเหลวของแต่ละ operation, การคืนรหัสข้อผิดพลาด และการประมวลผลแบบซับซ้อนผ่านฟีเจอร์ chain (subtransaction)

การออกแบบการทดสอบของ Jepsen

  • ใช้ไลบรารี Jepsen เพื่อทำ property-based testing และ fault injection
  • ทดลองกับคลัสเตอร์ 3–6 โหนดในสภาพแวดล้อมหลากหลาย เช่น LXC และ EC2
  • เนื่องจากข้อจำกัดของแบบจำลองข้อมูลทำให้ตรวจสอบความสอดคล้องแบบ list/set เดิมได้ยาก จึงใช้ ลำดับ operation ทั้งหมด (total order) เพื่อตรวจสอบความสอดคล้องของสถานะและเวลา
  • ตรวจจับข้อผิดพลาดด้วยวิธีที่เสริมกัน เช่น การตรวจความสอดคล้องตาม timestamp, model checking และ simulation

การตรวจสอบแบบจำลองและการสร้าง operation

  • ตรวจสอบความถูกต้องของการทำงาน TigerBeetle อย่างละเอียดด้วย แบบจำลอง state machine แบบ single-thread ขนาดกว่า 1600 บรรทัด
  • รองรับ การอนุมานและ rollback สำหรับเงื่อนไขข้อผิดพลาดหลากหลายแบบ เช่น id ซ้ำ, timestamp ไม่ต่อเนื่อง, ข้อจำกัดยอดคงเหลือ และ linked chain
  • เพื่อเพิ่มประสิทธิภาพในการตรวจสอบ มีการใช้ วิธีที่หลากหลาย เช่น การสร้าง operation/id, การอัปเดตสถานะ และการผสม query แบบอิงความน่าจะเป็น

การฉีดความขัดข้อง

  • ครอบคลุม สถานการณ์ความขัดข้องพื้นฐาน เช่น โปรเซสล่ม (SIGKILL), หยุดชั่วคราว (SIGSTOP), network partition และการเปลี่ยนนาฬิกา
  • มีการฉีดความขัดข้องของสตอเรจอย่างละเอียด เช่น การอัปเกรดเวอร์ชัน การจำลองไฟล์เสียหาย และความเสียหายบางส่วนเฉพาะบาง replica
  • ใช้หลายสถานการณ์ เช่น ความเสียหายของดิสก์แบบ zigzag (helical) เพื่อตรวจสอบการลดความเป็นไปได้ของข้อมูลสูญหาย

ตัวอย่างบั๊กสำคัญและรายละเอียดการปรับปรุง

ปัญหาในการจัดการ request timeout (#206)

  • ตามการออกแบบของ TigerBeetle คำขอจากไคลเอนต์จะไม่มีวัน timeout; จะ retry ไม่สิ้นสุดจนกว่าจะได้รับคำตอบจากคลัสเตอร์
  • แต่ในทางปฏิบัติ ไคลเอนต์อย่าง Java อาจเกิด timeout exception ระหว่างการทำงานแบบ async และแอปพลิเคชันก็มักต้องกำหนด timeout ภายนอกเอง
  • การออกแบบนี้ทำให้ แยกความต่างระหว่างความล้มเหลวแบบชัดเจนกับข้อผิดพลาดที่ยังไม่แน่ชัดได้ยาก เพราะมันซ่อนทั้งปัญหาเครือข่ายและข้อผิดพลาดที่แน่นอนไว้อย่างกำกวม
  • Jepsen แนะนำให้เพิ่มรูปแบบการคืนค่าตามประเภทความล้มเหลว (แน่ชัด/ไม่แน่ชัด) และ ตัวเลือกการ retry

JVM crash จากข้อผิดพลาดของไคลเอนต์ (#2435)

  • การห่อด้วย thread/async เพื่อหลบเลี่ยง timeout ทำให้เกิดปัญหา JVM segfault
  • เกิดจากการอ้างอิงฟิลด์ที่ยัง initialize ไม่ถูกต้องใน Java client และถูกแก้ไขใน 0.16.12

ไคลเอนต์ล่มเมื่อ session หมดอายุ (#2484)

  • เกิด การบังคับปิดไคลเอนต์ จาก session จำนวนมากเกินไป
  • ตั้งแต่ 0.16.13 ได้ปรับปรุงให้คืนค่าเป็นข้อผิดพลาดแทน

latency พุ่งสูงเมื่อโหนดเดี่ยวขัดข้อง (#2739)

  • จุดอ่อนของ replication แบบ ring ทำให้ เมื่อบางโหนดล้มเหลว เวลาตอบสนองโดยรวมเพิ่มขึ้นอย่างรุนแรง
  • สาเหตุคือโดยพื้นฐานแล้ว primary จะส่งข้อความไปยังโหนดถัดไปทีละขั้น ทำให้เมื่อบางโหนดล้มเหลวต้องรอเพราะไม่ได้รับ ack
  • หลัง 0.16.30 มีการนำ reverse replication และ dynamic ring topology มาใช้ ทำให้ ลดความหน่วงการตอบสนองระหว่างความขัดข้องได้มาก

บั๊กใน Header API ของ Java client (#2495)

  • มีการใช้ singleton object กับ response batch ว่าง ทำให้เกิด ปัญหาการแชร์ header และ timestamp ผิดพลาด
  • ไม่กระทบต่อความถูกต้องของข้อมูล แต่ทำให้ผลลัพธ์ของ Header API ปนเปื้อน และถูกแก้ใน 0.16.14

ผลลัพธ์ query หายบางส่วน (#2544)

  • มีรายงานบั๊กในเวอร์ชัน 0.16.13 ว่าผลลัพธ์ของ query_accounts, query_transfers ฯลฯ หายไปบางส่วน โดยผลตอบสนองถูกจำกัดไว้เพียง prefix ที่ถูกต้อง

บทสรุป

  • TigerBeetle เหมาะอย่างยิ่งกับ สภาพแวดล้อมด้านการเงินและบัญชีที่ต้องการความปลอดภัยสูงและการทนต่อความขัดข้อง
  • ชุดทดสอบของ Jepsen เผยให้เห็นประเด็นด้าน ความสามารถในการกู้คืน ความสอดคล้อง แบบจำลองการดำเนินการ และประสิทธิภาพ ที่หลากหลาย
  • ด้วยความร่วมมืออย่างต่อเนื่อง จึงเกิดการปรับปรุงที่เป็นรูปธรรมในด้าน การกู้คืนจากความขัดข้อง การจัดการข้อผิดพลาดของไคลเอนต์ การทำ replication และระบบอัตโนมัติของการอัปเกรด
  • ในเวอร์ชันล่าสุด ระบบมีความน่าเชื่อถือสูงขึ้นอย่างมาก ทั้งด้านการรับมือความขัดข้อง การรับประกันการเชื่อมต่อและการตอบสนอง และความสอดคล้องของ operation

(เนื้อหาบางส่วนนี้อ้างอิงจากโอเพนซอร์สหลายแหล่ง เช่น Github, เอกสารทางการของ TigerBeetle และรายงานการทดสอบ Jepsen)

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

 
GN⁺ 2025-06-07
ความคิดเห็นจาก Hacker News
  • โพสต์ Fuzzer Blind Spots (Meet Jepsen!) ก็เป็นข้อมูลอ้างอิงที่ควรอ่านด้วย โดยมีลิงก์แนะนำ https://tigerbeetle.com/blog/2025-06-06-fuzzer-blind-spots-meet-jepsen/

  • ขอแชร์ประสบการณ์ที่มักจะใช้รายงาน Jepsen เป็นด่านสุดท้ายในการตรวจสอบคำกล่าวอ้างเรื่องความน่าเชื่อถือและการสเกลของ TigerBeetle เสมอ รายงานครั้งนี้พบปัญหาหลายอย่าง แต่ก็ดูชอบแนวทางวิศวกรรมที่แก้ไขได้รวดเร็วและยังเสริม test suite ภายในเพื่อไม่ให้บั๊กลักษณะเดียวกันเกิดซ้ำ หากยังรักษาท่าทีแบบนี้ไว้ได้ ก็คาดหวังว่าอีก 10 ปีข้างหน้าในวงการฐานข้อมูลเฉพาะทางการเงิน TigerBeetle อาจขึ้นไปถึงสถานะค่าเริ่มต้นแบบ “ก็ใช้ Postgres ไปสิ” ได้เลย และขอยืนยันว่าได้เรียนรู้อะไรมากมายจากงานยอดเยี่ยมของ aphyr

    • TigerBeetle มี assertion มากกว่า 6,000 รายการ บางส่วนเข้มงวดเกินไปจนทำให้เกิด crash บ้าง แต่ก็เคยมีประสบการณ์ว่า assertion เหล่านี้ทำหน้าที่เตือนได้ตรงตามเจตนาเป๊ะ ๆ ในกรณีจริงนั้นมี correctness bug เล็ก ๆ เกิดขึ้นเฉพาะในฟีเจอร์ทดสอบภายในที่ใช้เพื่ออำนวยความสะดวกให้การตรวจสอบ Jepsen ฝั่ง Java client และยังมี correctness bug อีกหนึ่งจุดที่ไม่กระทบ durability ซึ่ง Jepsen เป็นผู้พบ รายละเอียดอธิบายไว้ใน ลิงก์นี้ TigerBeetle กำลังถูกออกแบบและทดสอบให้ทนต่อความขัดข้องได้มากกว่า Postgres โดยใช้แบบจำลองความขัดข้องของสตอเรจอย่างชัดเจน นำผลงานวิจัยที่ยังไม่มีในยุคที่ Postgres ออกมาวางจำหน่ายมาใช้ รวมถึง Deterministic Simulation Testing และมาตรฐานโค้ดความปลอดภัยของ NASA เพื่อรับประกันเสถียรภาพในหลายมิติ ในทางปฏิบัติ สำหรับสถานการณ์ที่มีหลักฐานในงานวิชาการชัดเจนว่า Postgres อาจทำข้อมูลสูญหาย TigerBeetle สามารถตรวจจับและกู้คืนได้ หากอยากดูรายละเอียดเพิ่มเติม แนะนำส่วน helical fault injection ของ Kyle หรือวิดีโอจากงาน QCon London นี้
    • ทุกครั้งที่อ่านรายงานของ Kyle จะรู้สึกเหมือนสกิลด้าน distributed systems ของตัวเองเพิ่มขึ้นอีกขั้น
  • รู้สึกดีใจที่ TigerBeetle ผ่านการตรวจสอบของ aphyr และทำได้ตามที่สัญญาไว้ ทำให้ยังพอมีความหวังว่าการทำสิ่งที่ถูกต้องจะนำไปสู่ผลลัพธ์ที่ถูกต้องได้ ในงานจริงข้อมูลที่อยู่นอกเหนือจาก Account หรือ Transfer มักจะถูกเก็บไว้ในระบบภายนอกและฐานข้อมูลอีกชุดหนึ่ง จึงอยากถามว่าปัญหาเรื่อง consistency และการกู้คืนระหว่างระบบภายนอกที่เชื่อถือได้น้อยกว่าเหล่านี้กับ TigerBeetle ในทางปฏิบัติจัดการกันอย่างไร

    • Zoran จาก TigerBeetle อธิบายรูปแบบการทำ integration ว่าโดยทั่วไปแนะนำสถาปัตยกรรมแบบแยก control plane (OLGP ทั่วไป เช่น Postgres) ออกจาก data plane (OLTP เช่น TigerBeetle) ข้อมูลผู้ใช้และสิ่งคล้ายกันเก็บใน OLGP ที่เป็นเหมือน “ตู้เอกสาร” ส่วนข้อมูลธุรกรรม (เช่น สินค้าคงคลัง → รถเข็น → การชำระเงิน) เก็บใน OLTP ที่เป็นเหมือน “ตู้เซฟ” โดยแบ่งบทบาทกันชัดเจน สามารถเชื่อมตัวระบุข้อมูลผู้ใช้ได้สูงสุด 3 ตัวต่อ account หรือ transfer เพื่อเชื่อม entity และ event ฝั่ง OLGP การแยกแบบนี้มีข้อดีด้านการสเกล การปฏิบัติการ และการดูแลที่เป็นอิสระจากกัน ตัวอย่างเช่นกรณีธนาคารที่ควรแยกเงินสด (ตู้เซฟ) ออกจากข้อมูล (ตู้เอกสาร) เพื่อให้เหมาะสม อีกทั้งความถี่ของธุรกรรมจริงกับความถี่การเปลี่ยนแปลงข้อมูลอย่างชื่อหรืออีเมลก็แตกต่างกัน จึงอธิบายได้ว่าทำไมโครงสร้างนี้สมเหตุสมผล สำหรับความสอดคล้องของข้อมูล ในเส้นทางการเขียนข้อมูลแนะนำให้บันทึกข้อมูลที่พึ่งพากันลง OLGP (รวมถึงสตอเรจภายนอกที่จำเป็นอย่าง S3) ก่อน แล้วค่อย commit เข้า TigerBeetle เป็นลำดับสุดท้าย ส่วนเส้นทางการอ่านให้ query TigerBeetle เป็น source of record เสมอ เพื่อรักษา strict serializability และสร้างความน่าเชื่อถือ แนบเอกสารสถาปัตยกรรมไว้ที่ ลิงก์นี้
  • หากเคยอ่านโพสต์เรื่อง fuzzer blind spot ของ Jepsen มาก่อน ก็จะยิ่งรู้สึกว่ารายงาน TigerBeetle ครั้งนี้น่าสนใจมากขึ้น กรณี segfault ฝั่ง JNI อาจไม่ถูกป้องกันแม้จะใช้ภาษา memory-safe อย่าง Rust แต่แนวทาง Zig/TigerStyle ของ TigerBeetle ก็ดูเป็นหลักฐานที่ดีในเรื่อง memory safety

    • มีประสบการณ์กับบั๊กจุดหนึ่งที่ Rust ก็ป้องกันได้เหมือนกัน แต่ในทางปฏิบัติ assertion ช่วยกันไว้ได้เป็นส่วนใหญ่ และถ้าไม่ได้ใช้ TigerStyle สถานการณ์ก็น่าจะอันตรายกว่านี้
  • ชอบไหวพริบในการตั้งชื่อหัวข้อ "Panic! At the Disk 0" มาก ขอปรบมือเบา ๆ แบบนักกอล์ฟให้เลย

  • ประทับใจกับรายงาน Jepsen แบบละเอียดฉบับนี้มาก ทั้งที่ยังไม่ถึง v1.0 ก็ยังคาดหวังสูงอยู่แล้ว และอยากชมเพิ่มเติมที่ผู้ก่อตั้งเข้ามาแชร์ insight ในเธรดอย่างกระตือรือร้น

    • ทั้งความละเอียดละออของ Kyle และความประณีตเชิงศิลป์ของรายงาน ทำให้อยากติดตามข่าวการพูดใหม่ของเขาที่ SD25 Amsterdam ด้วย
  • ในการทดสอบ distributed systems ประเด็นที่น่าสนใจคือการที่ระบบต้องรายงานลำดับ/เวลาเหตุการณ์ที่เกิดขึ้นภายในระบบเอง เพื่อนำไปเทียบกับโมเดลภายนอกอย่างแม่นยำ ซึ่งดูเป็นเงื่อนไขจำเป็นสำหรับการตรวจสอบที่ถูกต้อง และก็ให้ความรู้สึกว่า “จริงจนแทบไม่ต้องพูด”

    • ในสภาพแวดล้อมที่เป็น strict serializability วิธีนี้ทำได้ แต่ถ้าเป็นการรับประกันความสอดคล้องที่อ่อนกว่า ก็จะไม่สามารถมี global timeline เดียวได้ น่าสนใจในเชิงเมตาที่การยอมรับปัญหาที่ยากกว่ากลับทำให้ระบบง่ายขึ้น เช่น ถ้าเพิ่มโปรโตคอลสำหรับ disk failure/recovery เข้าไปเป็นพื้นฐาน ก็อาจได้ state sync ของ replica ที่ช้าเป็นของแถมไปด้วย เป็นต้น
  • หลังจากดูรายงาน Jepsen บล็อกที่เกี่ยวข้อง และโค้ดเชื่อมต่อกับ Antithesis แล้ว เลยอยากถามในเชิงเรียนรู้เรื่องขอบเขตและประสิทธิผลของการทดสอบ เข้าใจว่า TigerBeetle มีการทดสอบแบบครอบคลุมด้วย Antithesis อยู่แล้ว จึงสงสัยว่าบั๊กที่ Jepsen พบ หลุดจาก Antithesis ไปได้อย่างไร ความต่างระหว่างการทดสอบของ Antithesis กับ Jepsen คืออะไร และท้ายที่สุดขอบเขตการทดสอบภายในต่างกันอย่างไรแบบเจาะจง

    • aphyr เสริมว่า สำหรับ generative testing ของ distributed systems จำเป็นต้องมี 3 องค์ประกอบคือ 1) สภาพแวดล้อมที่ระบบทำงาน 2) load generator 3) auditor โดย Antithesis ทำหน้าที่หลักในข้อ 1 คือมอบสภาพแวดล้อมแบบ deterministic simulation ส่วน Jepsen แทรกความขัดข้องในระดับเครื่องจริงและระบบปฏิบัติการ ขณะที่ VOPR ของ TigerBeetle รันทั้งคลัสเตอร์อยู่ในเธรดเดียว วิธีจำลองแต่ละแบบต่างมีข้อดีข้อเสียที่ช่วยเสริมกัน กรณีบั๊กครั้งนี้หัวใจจริง ๆ คือข้อ 2) และ 3) หรือก็คือ workload generator และตัวตรวจสอบ auditor โค้ด Clojure เฉพาะสำหรับ TigerBeetle ของ aphyr เป็นตัวทั้งก่อให้เกิดและตรวจพบบั๊กนี้ หลังจากนั้นฝั่ง TigerBeetle ก็แพตช์โค้ดเทียบเท่าของตัวเองด้วย และข้อเท็จจริงคือปัญหาที่สำคัญกว่ากลับอยู่ที่ VOPR มากกว่าตัวฐานข้อมูลเอง สำหรับ distributed DB ย่อมมีโอกาสเกิดบั๊กได้เสมอ ดังนั้นสิ่งสำคัญจริง ๆ คือการออกแบบ generator และกลยุทธ์การทดสอบหลายแบบ
    • ในบล็อกของ TigerBeetle ก็อธิบายประเด็นนี้ไว้อย่างละเอียด สรุปคือการทดสอบที่ใช้ใน Antithesis ไม่ได้ครอบคลุมเงื่อนไข cross-query และค่าแบบ out-of-order ที่จำเป็นต่อการกระตุ้นบั๊กนี้ จึงพลาดไป ขณะที่ฝั่ง Jepsen จัดชุดเงื่อนไขนั้นได้พอดีเลยตรวจจับได้สำเร็จ และก็ย้ำด้วยว่าแม้แต่ test generator ของ Jepsen เองก็มีข้อจำกัดอยู่บ้าง จึงต้องออกแบบ generator ที่หลากหลาย
    • การทดสอบ internal latency simulation กว่า 90% ทำใน VOPR (simulator ภายใน) ซึ่งรันตลอด 24/7 บน CPU 1,000 คอร์ ส่วน Antithesis ใช้เป็นชั้นเสริมเพิ่มเติม หากอยากรู้ว่าทำไมบั๊กใน query engine ถึงหลุดรอดไปได้ แนะนำโพสต์ นี้
  • สนใจ TigerBeetle อยู่ และรู้สึกแปลกใจที่ในเอกสารไคลเอนต์ไม่มี C หรือ Zig client ทั้งที่ตัวระบบเขียนด้วย Zig เอง เลยอยากถามว่าไคลเอนต์นี้ยังไม่มีจริง ๆ หรือกำลังพัฒนาอยู่

  • สงสัยว่า TigerBeetle ถูกใช้งานแล้วในธนาคารใหญ่หรือบริษัทหลักทรัพย์หรือยัง

    • Zoran จาก TigerBeetle ระบุว่าปัจจุบันกำลังถูกนำไปใช้ร่วมกับ Gates Foundation เพื่อสร้างระบบชำระเงินดิจิทัลระดับชาติ 2.0 และธนาคารกลางอิเล็กทรอนิกส์ในลูอันดา ในระดับ enterprise ก็มีลูกค้าที่รันงานจริงและประมวลผลมากกว่า 100 ล้านธุรกรรมต่อเดือนอยู่แล้ว ล่าสุดเพิ่งเซ็นสัญญากับฟินเทคยูนิคอร์นยุโรปมูลค่า 2 พันล้านดอลลาร์ และในสหรัฐฯ ก็มีดีลเพิ่มเติมระหว่างดำเนินการ ทั่วโลกมีความต้องการนำ TigerBeetle ไปใช้เพิ่มขึ้นตามความต้องการประมวลผลธุรกรรมแบบเรียลไทม์ โดยผู้ก่อตั้งของ Clear Street ซึ่งเป็นโบรกเกอร์รายสำคัญบน Wall Street ก็ร่วมลงทุนด้วย ลิงก์ที่เกี่ยวข้องคือ mojaloop.io, บล็อกของ TigerBeetle, หน้าแนะนำบริษัท
    • ยังไม่ใช่ธนาคารใหญ่หรือกระดานเทรด แต่ตัวผมเองก็กำลังใช้อยู่กับสินค้าใหม่ในฟินเทครายใหญ่
    • คาดว่าเหตุที่ไม่มีชื่อใหญ่ ๆ มาอ้างอิงเป็นเพราะบริษัทไม่ได้เอามาโชว์บนหน้าเว็บ ตอนนี้ endorsement ที่ดูใหญ่ที่สุดน่าจะยังเป็นคำแนะนำจากยูทูบเบอร์ชื่อดังเสียมากกว่า