1 ポイント 投稿者 GN⁺ 2025-06-07 | 1件のコメント | WhatsAppで共有
  • 複式簿記向け OLTP データベース TigerBeetle は安全性と速度を前面に打ち出しており、Jepsen は 0.16.11〜0.16.30 系列を 3〜6 台の Debian クラスターで障害注入とともに検証した
  • テストでは、明示的な タイムスタンプ順序 とドキュメントベースの単一スレッド状態機械モデルを組み合わせ、Strong Serializability とアカウント・転送・クエリのセマンティクスをあわせて確認した
  • 主な安全性バグは、複数フィルタークエリの結果欠落と Java クライアントのヘッダータイムスタンプ誤りであり、0.16.26 以降では複数の障害の組み合わせでも Strong Serializability の主張と一致する結果が観測された
  • 可用性の面では、クライアントの無限リトライ、セッション eviction 時のプロセスクラッシュ、単一ノード障害での遅延急増、ディスクのビット反転・アップグレード中のサーバー panic、単一ノードのディスク損失に対する復旧経路の欠如が明らかになった
  • TigerBeetle 0.16.43 は報告された問題の大半を反映し、単一ノード障害時の遅延緩和と tigerbeetle recover を含んでおり、運用者は 0.16.43 へのアップグレードと 0.16.26 以上への移行時に リリースノートの確認 が必要である

TigerBeetle の設計とテスト範囲

  • TigerBeetle は複式簿記向けの OLTP データベースであり、任意の行・オブジェクト・グラフ・blob の代わりに、アカウント (accounts) と転送 (transfers) だけを保存する
  • Viewstamped Replication (VR) に基づいて Strong Serializable な一貫性を提供すると約束しており、金融取引・在庫・チケット販売・ユーティリティのメーター計測のようなモデルに合わせて設計されている
  • 高競合・高スループットのワークロードに合わせ、すべての書き込みを primary VR ノードの単一コアに通し、scale-out より scale-up に焦点を当てている
    • 性能のために、バッチ処理、I/O 並列化、固定スキーマ、固定サイズ・キャッシュ整列データ構造を使用する
  • 障害モデルは、メモリ、プロセス、時計、ストレージ、ネットワークを明示的に扱う
    • プロセスは停止またはクラッシュする可能性がある
    • 時計は前後にジャンプする可能性がある
    • ディスクは完全故障だけでなく、部分書き込み破損やデータ汚染も起こりうる
    • ネットワークは遅延、ドロップ、重複、誤配送、メッセージ破損を引き起こしうる
  • TigerBeetle は 決定論的シミュレーションテスト を使用しており、VOPR テストはクラスター全体と時計・ディスク・ネットワークのインターフェースをシミュレーションする

データモデルとリクエストのセマンティクス

  • データモデルは accountstransfers の 2 種類のレコードで構成される
    • アカウントは、ユーザー定義の 128 ビット idledgerflagstimestampcodeuser_data_32user_data_64user_data_128 などを持つ
    • 転送は、debit_account_idcredit_account_idamountledgerflags、ユーザー定義フィールドなどを含む不変レコードである
  • 転送は単一段階で即時に post でき、pending と post/void に分かれる 2 段階転送 も可能である
    • pending transfer は debit・credit アカウントの容量を予約する
    • その後、pending amount 以下を post するか void できる
    • timeout フィールドで自動失効を制御する
  • アカウントは closed フラグと 4 つの残高フィールドを除いて不変であり、転送は常に不変である
    • 転送を変更または巻き戻すには、補償転送を新たに作成しなければならない
  • リクエストは単一種類の論理演算を表し、通常は最大 8190 イベント のバッチを含む
    • create_accountscreate_transfers は書き込みリクエストである
    • lookup_accountslookup_transfersquery_accountsquery_transfersget_account_transfersget_account_balances は読み取りリクエストである
  • 各リクエストはデータベースの観点では 1 つのトランザクションだが、コミット済みリクエスト内の一部イベントは論理的に失敗し、エラーコードを返すことがある
    • イベント間の条件付き原子性が必要な場合は chain を使用し、同じ chain 内のイベントがすべて成功するか、すべて失敗するようにする

Jepsen のテスト方式

  • Jepsen テストスイートは Jepsen testing library を使って、プロパティベーステストと障害注入を組み合わせる
  • テスト対象は TigerBeetle 0.16.11 から 0.16.30 までで、複数の開発ビルドも含まれる
    • クラスターは 3〜6 台の Debian ノードで構成される
    • LXC コンテナと EC2 VM の両方で実行される
  • TigerBeetle の公式クライアントはすべてのノードに接続する smart client であるため、並行性エラーを隠してしまう可能性がある
    • Jepsen は通常の smart-client 動作もテストする
    • 同時に、各クライアントを単一ノードに制限する方式も用いる
  • 検証器は 2 段階で動作する
    • 成功したリクエストの実行タイムスタンプを読み取り、失敗・タイムアウトした書き込みについては、その後に観測された効果からタイムスタンプを推論する
    • 推論されたタイムスタンプ順に、ドキュメントベースの TigerBeetle 状態機械モデルを実行し、結果とエラーコードを検証する
  • 状態機械モデルは 1,600 行以上の Clojure で書かれており、アカウント・転送マップ、インデックス、一時的エラー、内部統計、時計の進行などを含む
    • 重複 ID、非単調タイムスタンプ、残高制約、互換性のないフラグ、chain の speculative execution と rollback などを処理する
    • 高性能永続データ構造ライブラリ Bifurcan を使用する

障害注入とファイル破損テスト

  • Jepsen はプロセス SIGKILLSIGSTOP、複数形式のネットワークパーティション、ミリ秒から数百秒までの時計変更、高速な時計の往復変更を注入する
  • テスト中には複数バージョンへの ノードアップグレード も実施した
  • 新しいファイル破損 nemesis により、さまざまなストレージ障害を作り出した
    • ランダムなビット反転で宇宙線干渉のような破損をシミュレートする
    • ファイルチャンクを別のチャンクで置き換え、misdirected write をシミュレートする
    • ファイルチャンクのスナップショットを後で復元し、lost write をシミュレートする
  • TigerBeetle ノードは単一のデータファイルを持ち、ファイルは予測可能な offset の zone に分かれている
    • WAL header、superblock zone の冗長 copy など、特定の zone だけを破損させるテストを実施した
    • 複数の zone やファイル全体を破損させるテストも含まれる
  • “helical” disk fault は、すべてのノードのファイルを破損させつつ、各ノードごとに異なるチャンクを破損させる方式である
    • TigerBeetle の最新 replica ファイル配置は一般に bit-for-bit で同一であるため、単一レコードがすべての replica で復旧不能に破損する状況を避けることが目的である
    • WAL の head はノードごとに位置が異なる可能性があり、例外となる

発見された安全性の問題

  • 0.16.13 では、query_accountsquery_transfersget_account_transfers の応答で、結果の一部または全部が欠落する問題が頻繁に発生した
    • 欠落した結果は常に応答の末尾部分であり、応答は正しい結果の prefix になっていた
    • 単一フィルターのクエリでは発生せず、ledgercode のような複数フィルターの組み合わせで発生した
    • 原因は、複数インデックス間の zig-zag merge join における bounds check のバグだった
    • #2544 で追跡され、0.16.17 で修正された
  • 0.16.13 に Jepsen テスト支援用として追加された Java クライアントのヘッダー API が、誤った、または重複した実行タイムスタンプを返していた
    • 原因は、Java クライアントの mutable singleton 応答オブジェクト Batch.EMPTY だった
    • 成功応答が空の batch として表現されることで、複数の応答が同じオブジェクトの header を上書きしていた
    • #2495 で修正され、0.16.14 に反映された
    • 実際のデータ整合性には影響せず、Java クライアントの header API のリクエストタイムスタンプにのみ影響した
  • 0.16.26 以降で観測された結果は、TigerBeetle の Strong Serializability の主張と一致している
    • プロセス pause、crash、ネットワーク partition、clock error、disk corruption、upgrade の組み合わせでも、この性質は維持された

クライアントとリクエスト処理の問題

  • TigerBeetle のドキュメントでは、リクエストは timeout せず、クライアントが応答を受け取るまで継続的に retry すると説明している
    • Java の非同期メソッドは CompletableFuture を返し、.get(timeout, timeUnit).orTimeout(...) のような timeout API を使用できる
    • .NET クライアントの Task も timeout ベースの Wait() を提供する
  • 無限 retry は definite error と indefinite error の両方を隠してしまう可能性がある
    • たとえば、TCP 接続が ECONNREFUSED で失敗した場合、その元のリクエストは実行されえない definite failure である
    • しかし、クライアントがこれを呼び出し元に通知せず、内部 retry だけを続けると、呼び出し元の観点では timeout や中断のような indefinite failure になる
  • この問題は #206 で議論中であり、レポート時点では unresolved だった
    • Jepsen は definite error と indefinite error を第一級のものとして表現し、呼び出し元に返すことを推奨している
    • 自動 retry 自体は維持してもよいが、設定可能であるべきであり、接続開始と応答待機の最大時間をオプションとして持たせることを推奨している
  • 0.16.11 の Java クライアントでは、timeout 処理のために同期呼び出しスレッドを interrupt したり、非同期呼び出し後に client を close したりすると、JVM 全体が segfault する問題があった
    • 原因は request data structure の未設定フィールドだった
    • クライアントが request の生成と送信の間に閉じられると、Zig のデフォルト値である 0xaaa... アドレスを逆参照していた
    • #2435 で修正され、0.16.12 に反映された
  • 公式クライアントは、サーバーが session eviction を通知したときにプロセス全体を crash させていた
    • TigerBeetle はデフォルトで concurrent session を 64 個に制限している
    • サーバーより新しいクライアントバージョンを使っている場合にも eviction が発生する
    • #2484 以降、0.16.13 からは eviction 時にプロセスを crash させる代わりに、呼び出し元へ error を返すようになった

単一ノード障害時のレイテンシ急増

  • 単一ノード障害時に client latency が 3~5 桁増加する事例が繰り返し見られた
    • 5 ノードクラスタで単一ノードを停止させると、minimum latency が 1ms 未満から 10 秒へ増加した
    • 3 ノードクラスタで 1 ノードを停止させたテストでは、1~50ms だった latency がリクエストあたり約 100 秒まで増加し、ノード再起動前までほぼ 1000 秒間継続した
  • 原因は TigerBeetle の prepare 伝播方式に関連している
    • 従来の VR では、primary がすべての secondary に prepare を送り、ack を直接受け取る
    • TigerBeetle ではノードを ring 状に配置し、primary が次の secondary に prepare を送ると、各 secondary が次のノードへ転送する
    • この方式は 1 ノードあたりの bandwidth 要求を減らすが、ring の次の f 個の replica のうち 1 つが故障すると commit が妨げられることがある
  • この問題は #2739 で追跡されている
  • 0.16.30 では、prepare メッセージの半分を ring の反対方向に送る方式で緩和した
    • 一部の prepare が故障ノードを迂回できる
    • Jepsen テストでは、100 秒台の latency が 1~30 秒程度まで減少した
  • 0.16.43 には追加の性能改善が含まれている
    • ノードが ring の両方向に replicate する
    • ring topology が動的に変化し、クラスタがネットワーク条件や障害に応じてノード順序を調整する

ディスク破損とサーバー crash

  • 0.16.20 では、superblock、WAL、grid zone の単一ビット破損が startup crash を引き起こす場合があった
    • ログには panic: reached unreachable code が出力されて終了していた
    • 原因は sector padding 検査のバグだった
  • TigerBeetle の checksum はチャンクのデータはカバーするが、padding は対象外である
    • padding の 0 ビットが 1 に変わっても checksum は通過する
    • その後、padding が依然として 0 かどうかを確認する assertion が失敗し、サーバーが crash する
    • padding の破損は safety を損なわず、再び 0 に戻すか、別の replica から復旧できる
  • VOPR は従来、sector 全体を破損させていたため、このバグを見つけられなかった
    • sector の破損は checksum failure と repair パスを引き起こし、padding assertion には到達しなかった
    • TigerBeetle は #2681 で VOPR に single-byte error を追加した
    • 0.16.26 からは、padding が破損した sector を crash ではなく repair するようになった
  • superblock の copy number のビット反転も同じ panic を引き起こす可能性があった
    • superblock の 4 つのコピーはそれぞれ異なる 2 バイトの copy 番号を持ち、checksum はこの番号をスキップする
    • ディスク上で破損した copy number がメモリに読み込まれた後、書き込み時に 0~3 の範囲 assertion に失敗していた
    • 0.16.26 では copy number を reset する方式で解決された

アップグレード関連の問題

  • 0.16.25 以下から 0.16.26 以上へアップグレードする際、panic: checkpoint diverged クラッシュが繰り返し観測された
    • 原因は 0.16.26 における CheckpointState 構造の変更だった
    • 新バージョンは released blocks の集合を含んでいたが、旧バージョン互換の状態転送過程でこの情報が空になる可能性があった
    • その後ノードが 0.16.26 で再起動すると、ほかの replica が知っている released blocks を失った状態になる可能性があった
    • assertion が divergence を検知してクラッシュし、クライアントが不整合なデータを観測できないようにした
  • この問題は #2745 として changelog に文書化された
    • TigerBeetle はパッチ済みの 0.16.26 をリリースしていない
    • 運用者は 0.16.26 以上へアップグレードする前に client を停止し、replica の catch-up を待つ必要がある
  • 0.16.16 から 0.16.28 まで複数の upgrade を約 20 秒以内に連続実行した場合、または upgrade 中にノードが pause/crash した場合、release_transition assertion failure が発生する
    • 実行中のノードは新しい binary を memfd で開いて exec() で置き換えるが、その間にディスク上の binary がさらに新しいバージョンへ置き換えられることがある
    • コードがディスク上の version header まで現在の実行バージョンと同じだと assertion して失敗する
    • #2758 により、0.16.29 では assertion は warning に変更された
  • 0.16.26 から 0.16.27 へアップグレードする際、deprecated message type によって panic: switch on corrupt value が発生した
    • 新しいノードの switch 文に古いメッセージ型の case がなく、クラッシュした
    • #2763 により、0.16.29 で deprecated message type を再び case に入れて無視するよう修正された

単一ノードのディスク損失からの復旧

  • TigerBeetle はファイル破損に強いが、ディスク障害・火災・EBS volume error・運用者のミスなどにより、ノードのデータファイル全体が失われたり、復旧不能なほど破損したりする可能性がある
  • 報告時点のドキュメントには障害ノードの置き換え方法がなく、未文書化の recovery 手順として tigerbeetle format を実行して空のデータファイルで初期化し、その後 repair に期待する方式があった
  • Jepsen は、reformat は大半の場合は動作するが、安全ではない可能性があることを確認した
    • 3 ノード中 2 ノードに committed operation op があり、そのうち 1 つを reformat すると、op を観測していない 2/3 majority が view change を実行して operation が失われる可能性がある
    • 実際のテストでは、acknowledged transfer 5 件が失われた run があった
    • upgrade 中に、newer binary で format されたノードが cluster version transition を完了する前に startup crash する例もあった
  • この問題は #2767 として追跡されている
  • その後、TigerBeetle 0.16.43 には catastrophic data loss を経験したノードを復旧する tigerbeetle recover コマンドが含まれた

Jepsen の結論と推奨

  • 発見された安全性の問題は 2 つだった
    • 0.16.17 より前での複数フィルタクエリ結果の欠落
    • Jepsen テスト用 Java クライアントのデバッグ API における誤った・重複したタイムスタンプ
  • クラッシュ問題は合計 7 件だった
    • Java クライアント 2 件: 未初期化メモリアクセス、eviction 時のプロセスクラッシュ
    • サーバー 5 件: ディスク破損関連 panic 2 件、アップグレード関連 panic 3 件
    • #2745 は文書化され、残りのクラッシュは 0.16.29 までに解決された
  • 0.16.43 は、レポート中の 1 件を除くすべての問題を解決している
    • 未解決項目は、client request が設計上継続して retry される問題である
  • ユーザーへの推奨は明確だ
    • 0.16.43 にアップグレードすること
    • 0.16.26 またはそれ以降のバージョンへ移行する際は release note を確認すること
    • テスト環境で単一ノード障害をシミュレーションし、アプリケーションが増加した latency にどう反応するかを測定すること
  • TigerBeetle のアーキテクチャは sound に見え、VR・flexible quorum・protocol-aware recovery の統合が Strong Serializability の中核不変条件を損なっていないことが観測された
  • ただし Jepsen の検証は実験的アプローチであり、バグの存在は証明できても、不在は証明できない

1件のコメント

 
GN⁺ 2025-06-07
Hacker News のコメント
  • あわせて読みたい記事: Fuzzer Blind Spots (Meet Jepsen!) – https://tigerbeetle.com/blog/2025-06-06-fuzzer-blind-spots-m...

  • このレポートは本当に印象的。TigerBeetle の信頼性とスケーラビリティに関する主張を見るたびに、「よし、Jepsen レポートを待とう」と思っていた。
    レポートではいくつもの問題が出てきて、懸念することもできるが、単に修正して終わりではなく、今後似たようなバグを捕まえられるよう内部テスト群を拡張した点は前向きに見られる。こういうエンジニアリングの姿勢なら、10年後の TigerBeetle は金融アプリケーションのニッチで「もう Postgres でいいじゃん」と言われるレベルの標準的なデータベースになっているかもしれない。
    aphyr の仕事も素晴らしく、レポートを読んで多くを学んだ気がする。

    • TigerBeetle には6,000個以上の assertionがあり、一部は厳しすぎてクラッシュを引き起こしたが、その assertion たちは役割を果たし、mental model を調整すべきだというシグナルを出し、実際に調整された。
      それ以外では、Jepsen 監査を支援するために Java クライアントにだけ入れた内部テスト機能の小さな正確性バグを除けば、Jepsen が見つけた正確性バグは1件だけで、耐久性には影響しなかった。関連する記事はこちら: https://tigerbeetle.com/blog/2025-06-06-fuzzer-blind-spots-m...
      公平に言えば、TigerBeetle は Postgres より多くの障害に耐えるよう設計・テストされている。明示的なストレージ障害モデルを持ち、Postgres が1996年に登場した時点では存在しなかった研究成果を活用しているからだ。TB の障害モデルは決定論的シミュレーションテストで追加検証され、NASA の Safety-Critical Code 向け Power of Ten Rules に従った静的メモリ割り当てのような手法も使っている。文献上、Postgres がデータを失う既知のシナリオがあるが、TigerBeetle はそれを検知して復旧できる。
      さらに知りたければ、Kyle のレポートの helical fault injection セクションを見るとよい。ほとんどの Raft や Paxos 実装はこれに耐えるよう設計されておらず、QCon London の発表もある: https://m.youtube.com/watch?v=_jfOk4L7CiY
    • Kyle の記事はいつも楽しみ。新しい記事が出るたびに、分散システムの知識が一段上がる感じがする。
  • aphyr が検証した結果、TigerBeetle が自分たちの主張に沿った姿を見せてくれて本当にうれしい。正しいアプローチを取れば正しい結果が出る、というのを見るのは良いことだ。
    TigerBeetle が実際にどう使われることになるのか気になる。Account や Transfer 以外のすべてのために、TigerBeetle のインストールの周辺には外部システムや別のデータベースがたくさんあるはずだが、そうした信頼性の低いシステムが TigerBeetle と足並みをそろえる典型的なパターンは何なのか、特に両者の間で一貫性の問題が起きたときにどう復旧するのかが気になる。

    • TigerBeetle を統合するときの典型的なパターンは、制御プレーンデータプレーンを分けること。汎用目的または OLGP には Postgres を使い、トランザクション処理または OLTP には TigerBeetle を使う。
      ユーザー情報(名前、住所、パスワードなど)や商品情報(説明、価格など)は「書類棚」として OLGP に入れる。
      そしてブラックフライデーに、ユーザーが商品を在庫アカウントからカートアカウントへ、さらに決済アカウントや配送アカウントへ移すすべてのトランザクションは、「金庫」として OLTP に入れる。TigerBeetle はアカウントや送金ごとに最大3つのユーザーデータ識別子を保存できるので、エンティティ間のイベントを、そのエンティティを説明する OLGP データベースと結びつけられる。
      このアーキテクチャ [1] は明確な関心の分離を提供し、異なるワークロードを独立にスケール・管理できるようにする。銀行なら、顧客記録が入った書類棚に現金をすべて保管するよりも、性能・コンプライアンス・保存特性が異なる現金は金庫に保管するほうが理にかなっている。
      このパターンが適している理由は、ユーザーが名前やメールアドレスを変更する頻度(OLGP)が、取引する頻度(OLTP)よりはるかに低いからだ。
      一貫性を保つには、書き込み経路で TigerBeetle を OLTP データプレーンかつ「記録の源泉」として扱う。「カートへ移動」や「決済」トランザクションが入ってきたら、まず必要なデータ依存関係を OLGP に書き込み、関連する blob データがあれば S3 のような場所にも書き込み、その最後に TigerBeetle に書き込んでトランザクションをコミットする。読み取り経路では、厳密な直列化可能性を保つために記録の源泉を先に参照する。
      [1] https://docs.tigerbeetle.com/coding/system-architecture/
  • TigerBeetle のファザーの死角に関する記事を読んだあとで見ると、特に面白いJepsen レポートだ。
    JNI 側のセグフォは、Rust や他のメモリ安全な言語を使っていても防げなかったように見える。メモリ安全性のバグがほとんどないという点は、TigerBeetle の Zig プログラミング手法、記憶では TigerStyle が意図した役割をかなりうまく果たしている証拠に見える。

    • https://news.ycombinator.com/item?id=44201189 を参照。Rust だったら救えたバグが1つあったのは確か。ただし assertion が救ってくれたので、ベーコンは少しカリカリになっただけで焦げずに済んだ。
      それでもその通り。TigerStyle がなければ nasal demons にやられていただろう。
  • 見事なまでに詳細なレポートで気に入った。Jepsen がテストし、署名したということは、TigerBeetle にとって非常に大きな保証になる。まだ v1.0 にも到達していないのに、今後の新たなマイルストーンが楽しみだ
    このスレッドで優れた洞察を共有している創業者たちにも、特に拍手を送りたい

    • Kyle は驚くべき仕事をしたし、レポートに含まれるディテールも本当に素晴らしかった。読んでいる間ずっと「これは芸術作品のようだ」と思ったほど、職人技と精密さを感じた
      近く Amsterdam の SD25 での発表でも新しい内容を共有する予定なので楽しみだ
  • 「Panic! At the Disk 0」というセクションタイトルが、ささやかながら気に入った

  • テスト対象の分散システムが、実際に事象が発生した時刻と順序を報告する必要があり、壁時計時刻を使う代わりにシステムの外部モデルと正確に検証できる、という点は後から考えると当然だが興味深い

    • これが機能するのは、厳密な直列化可能性があるからだ。より弱い一貫性保証では、単一のグローバルに一貫したタイムラインが必ず存在するわけではない
      より難しいことをやり遂げると、かえってシステムが単純になるという興味深いメタパターンだ
      別の例として、ディスクは失敗し得ると仮定して復旧プロトコルを含める必要があるため、遅れたレプリカの状態同期が実質的に「無料で」手に入る。ディスク全体が破損した状況と、まったく同じ問題だからだ
    • これは古典的なアプローチだと思う。例: https://lamport.azurewebsites.net/pubs/time-clocks.pdf
  • 記事中の「Viewstamped Replication」論文へのリンクが、残念ながら壊れている。https://pmg.csail.mit.edu/papers/vr-revisited.pdf は接続が拒否される
    おそらく http://pmg.csail.mit.edu/papers/vr-revisited.pdf のように、https ではなく http スキームであるべきなのだと思う
    これで金曜の夜に読むものができた

    • 近いうちに修正される予定だ
      VSR 2012 の論文は最も好きな論文の一つで、「Protocol-Aware Recovery for Consensus-Based Storage」も本当に強力だ
      楽しく読んでほしい
  • 純粋に学びたくて聞いている質問で、誤解されないことを願う。分散システムは学び始めたばかりで、決定的シミュレーションテストに魅了されている
    TigerBeetle に関する Jepsen レポート、関連するブログ記事、GitHub ワークフローでの Antithesis 統合コードをざっと見て、テスト範囲をもっとよく理解したくなった
    核心的な疑問は、Jepsen のテスト群が見つけたこれらのバグを、Antithesis 統合でも見つけられたのかということだ
    いくつかの仮定に基づく質問なので、間違っているかもしれない。TigerBeetle はすでに内部テスト群と Antithesis 製品で包括的にテストされていると思っていたし、Antithesis のテスト群は Jepsen より強力だと理解していたので、Jepsen が Antithesis では見つけられなかった問題を発見したことが意外だった
    自分の理解が間違っているのか知りたい。たとえば、1) Antithesis のテスト群ではこの特定の種類のバグを検出できなかったのか、2) システムのこの部分がまだ Antithesis のテストでカバーされていなかったのか、3) Jepsen と Antithesis のテスト群の異なる強みや目的を誤解していて、リンゴとオレンジを比較しているのか、という点を知りたい

    • TigerBeetle のブログ記事により詳しく書かれているが、簡単に言うと、Antithesis で走っていたテストはかなり徹底的だったにもかかわらず、交差するクエリ順序が入れ替わった値の正確な組み合わせを作れず、Jepsen の生成器がその組み合わせを引き当てた
      Jepsen のテスト生成器にも、ほぼ間違いなく死角はある。だからこそ、異なる生成器を設計することが役に立つ
    • 分散システムの生成的テストには、通常 3 つの構成要素が必要だ。第一に、システムを実行する環境が必要だ。最も単純には実マシンのクラスタを立ち上げることだが、性能、外部 API 応答の制御、決定性、再現性を高めるには、より精巧なものが望ましい。第二に、環境内のシステムに興味深いことをさせる負荷生成器が必要だ。第三に、負荷がかかったシステムの動作を観察し、仕様に合っているか判断する監査器が必要だ
      Antithesis は主に 1 番目の問題を扱い、仮想マシンによって決定的シミュレーション環境を提供する。同じ問題を Jepsen は実マシンを使いつつ OS レベルで障害を注入する方法で扱い、TigerBeetle 独自の VOPR はデータベースと一緒に設計されており、クラスタ全体を単一スレッドで実行できる。この 3 つのアプローチは相互補完的で、それぞれ得意領域が異なる
      このバグで決定的だった部分は 2 番目と 3 番目、つまりバグを実際に引き起こせるワークロード検証器と監査器を書くことだった。ここでは aphyr が書いた TigerBeetle 専用の Clojure コード 1,600 行がバグを引き起こして検出し、その後 TigerBeetle 側の同等のテストもこれを引き起こすようにパッチされた。実のところ、ここでバグがあるのはデータベースというより VOPR だ。データベースにバグがあるのは当然のことで、意志の力だけでバグを避けることはできない。だからこそ、ほとんどのバグを引き起こせるテスト戦略が必要で、すり抜けたバグはワークロード生成器の欠陥を示している
    • 決定的シミュレーションテストの 90% は、主に TigerBeetle が自作した決定的シミュレータ VOPR が担っている。専用 CPU コア 1,000 個規模で 24/7 稼働している
      Antithesis も使っているが、決定的シミュレーションテストの第 2 層として使っている
      クエリエンジンのバグがなぜすり抜けたのかは、こちらを参照: https://tigerbeetle.com/blog/2025-06-06-fuzzer-blind-spots-m...
  • 大手銀行や証券取引所が TigerBeetle を使っているのか気になる

    • 国家レベルでは、Gates Foundation とともに TigerBeetle を非営利の中央銀行スイッチに統合しており、このシステムは今年後半に Rwanda の National Digital Payments System 2.0 を稼働させる予定 [1]
      企業レベルでは、TigerBeetle はすでに月間1億件以上のトランザクションを処理する顧客の本番環境で使われており、最近ヨーロッパの20億ドル規模のフィンテック・ユニコーンと初契約を結び、米国でも数件が間もなくまとまる予定。世界的にリアルタイム・トランザクション処理へ移行する流れ [2] があるため、より高い性能を求めて TigerBeetle へ移行したい企業からかなり関心が寄せられている
      質問に答えると、Wall Street のかなり大きなブローカレッジである Clear Street の創業者の一部が TigerBeetle に投資 [3] している
      [1] https://mojaloop.io/how-mojaloop-enables-rndps-2-0-ekash/
      [2] https://tigerbeetle.com/blog/2024-07-23-rediscovering-transa...
      [3] https://tigerbeetle.com/company
    • 銀行や取引所ではないが、非常に大きな フィンテック企業 で働いていて、新規プロダクトに TigerBeetle を使っている
    • そういう顧客がいたなら、ホームページで誇示していたはずだと思う。これまでホームページで最大のお墨付きは、ある YouTuber からのものだった。人気 YouTuber なのは確かだが、それでも YouTuber だ