TigerBeetleは世界で最も興味深いデータベースである
(amplifypartners.com)- 金融取引データベース TigerBeetle は、借方(debit) と 貸方(credit) をネイティブサポートする新しいデータベースで、既存のSQLデータベースが1件の取引に10〜20回のクエリを必要としていたのに対し、単一ラウンドトリップで8,190件の取引を処理
- 多くのシステムが高速なコーディングと依存関係の拡大を選ぶ一方、このプロジェクトは コードをゆっくり書くこと、決定論的シミュレーションテスト(DST)、ゼロデペンデンシー のような反常識的な戦略を貫いている
- 単一ノードアーキテクチャに依存する既存のOLTPデータベースと差別化し、分散をデフォルトに、時計障害耐性(cluster time)、ストレージ障害耐性を設計に組み込み、Viewstamped Replication と Zig の採用によって実装の単純さと可視性を確保
- NASAのPower of Tenに着想を得た TigerStyle手法 を適用し、関数ごとに平均2個以上のassertionを使用、静的メモリ割り当てを強制し、プロダクション環境でもassertionを有効化するなど、厳格なコーディング標準を順守
- リアルタイム決済・ゲーミング・エネルギー課金など 超トランザクション化時代 に合わせた構造で、次世代OLTPの 性能・正確性のベンチマーク を提示し、既存の20〜30年前のSQLデータベースを置き換える 次世代トランザクション処理システムとして台頭
借方/貸方中心データベースの必要性
- TigerBeetleは「金融取引データベース」として 借方(debit)と貸方(credit)を中核プリミティブ として使用
- 1985年にJim Grayが定義したトランザクションの本質は、SQLトランザクションではなく ビジネストランザクション(借方/貸方) だった
- Grayは20年後にも標準的なトランザクション処理を「DebitCredit」と定義した。銀行口座から借方処理を行い、複式簿記を実行した後、端末に応答するというもの
- 借方/貸方は単に会計や銀行のためのものではなく、取引の本質を表す共通言語 であり、ACIDのような保証を提供する理由でもある
- 既存のSQLデータベースで借方/貸方を実装する際の問題点
- 1つの借方/貸方処理のために、口座残高の照会、行ロック、コード内での意思決定待ち、借方/貸方の記録など 10〜20回のSQLクエリ が必要
- ネットワーク往復時間のあいだ行ロックを維持しなければならず、多くの取引が同じ「ハウス口座」にアクセスするホットロウ問題も悪化
- インドやブラジルでの月間数十億件の即時決済、米国のFedNow、エネルギー・ゲーム・クラウドのリアルタイム課金などにより、世界は 10年以内に少なくとも3桁規模でさらにトランザクション中心 になったが、現在使われているSQLデータベースは20〜30年前の技術
- TigerBeetleの差別化ポイント
- 借方/貸方を 第一級プリミティブ として設計し、単一の1MiBクエリで8,190件の取引を1回のラウンドトリップで処理
- 創業者Joranはこれを「1000x performance idea」と呼ぶ一方で、「特別なことではない」と表現
- 一般にデータベースの構築には10年かかるが、TigerBeetleは 3.5年で完成 し、Jepsenテストを通過
- 2025年6月、Kyle Kingsburyは全マシン上のさまざまな箇所を破損させてもTigerBeetleの基盤を壊せず、耐久性に影響しない読み取りクエリエンジンで1件の正確性バグを発見したのみだった
現代的なデータベース設計
分散前提のアーキテクチャ
- PostgresやMySQLが構築された時代には 単一ノード パラダイムが支配的だったが、現在の共有クラウドハードウェア時代では 分散 パラダイムが主流
- 現代のデータベースは厳密な直列化可能性を提供し、マシン間でトランザクションを複製して冗長性、障害耐性、高可用性を確保する必要がある
- 現在最も人気のあるOLTPデータベースの一部は、なお単一ノードアーキテクチャに大きく依存しており、自動フェイルオーバーが標準で組み込まれていない場合もある
- TigerBeetleの分散設計
- デフォルトで分散 するように構築されており、クラスター内の任意の台数のマシンにバイナリを配置するだけでよい
- 非同期レプリケーションやZookeeperは不要で、MITの先駆的な Viewstamped Replication コンセンサスプロトコルの実装に投資
- Zigツールチェーンを除いて ゼロデペンデンシー を維持し、すべての中核依存要素に直接投資
クロック障害耐性
- TigerBeetleはトランザクションデータベースとして、物理タイムスタンプの正確性 が監査と規制遵守のために重要
- Linuxには複数のクロックがある:
CLOCK_MONOTONIC_RAW,CLOCK_MONOTONIC,CLOCK_BOOTTIME - ハードウェアクロックの物理的不完全性により、クロックが異なる速度で動作して「drift」エラーが発生し、短時間で「skew」エラーとして蓄積
- 通常はNTPがこれらのエラーを補正するが、部分的なネットワーク障害でNTPが静かに停止すると、高可用性コンセンサスクラスターが暗闇の中で動作し続ける可能性がある
- Linuxには複数のクロックがある:
- クラスタータイムの実装
- クラスター内の 多数派のクロックを結合 して、障害耐性のある「クラスタータイム」を構成
- 必要に応じてサーバーのシステム時刻を再調整し、不良クロックが多すぎる場合は安全に停止
- Chrony、PTP、NTPが停止した場合を実際に検知し、オペレーターに警告
- サーバー間のオフセットクロック時間を追跡・サンプリングし、Marzulloアルゴリズム により最も正確な区間推定を算出
ストレージ障害への対応
-
従来のデータベースの前提
- ディスク障害時にはエラーメッセージとともに予測可能に失敗すると仮定
- SQLiteのドキュメント: 「SQLiteは破損やI/Oエラー検出のためにデータベースファイルへ冗長性を追加せず、読み取ったデータが以前に書き込んだデータと正確に同一であると仮定する」
-
実際のストレージ障害シナリオ
- ディスクが静かに破損データを返す、I/Oが誤った方向に渡される(読み取り/書き込みパス)、エラーコードなしで突然遅くなる gray failure などが発生しうる
-
TigerBeetleのストレージ障害耐性
- Protocol Aware Recovery を用いることで、全レプリカ上のデータコピーが破損しない限り可用性を維持
- すべてのデータは不変であり、チェックサムとハッシュチェーンによって破損や改ざんがないことを強力に保証
- 独自のページキャッシュ、O_DIRECTによるディスク書き込み、ファイルシステム不要の生ブロックデバイス上での直接実行により、ディスクとソフトウェアの間のレイヤーを最小化
- 既製のLSMではなく、自前実装の LSM Forest(約20本のLSMツリー)を使用
- ストレージ障害耐性を主張するだけでなく、Jepsenによって検証された唯一の分散データベース
- ローカルマシン障害時には、ディスクセクター単位の故障であってもストレージエンジンがグローバルコンセンサスに接続され、クラスターを通じて自己修復する
Zigプログラミング言語の選択
-
従来のデータベースの言語
- PostgresはC(1970年代)、MySQLはCとC++(1979年)、MSSQLもCとC++で書かれている
- プログラミング言語はこの40年で大きく進化しており、現代的に構築するならRustやZigを選べる
-
TigerBeetleがZigを選んだ理由
- Cエコシステム全体を活用でき、優れたツールチェーンとコンパイラを提供
- 書きやすく、とりわけ 読みやすい。場合によってはTypeScript並みに容易でありながら、はるかに高速
- 静的メモリ割り当て が可能で、これはTigerBeetleの中核原則
- 優れた開発者体験により、学習が速く、TigerBeetleのソースコードにもすばやく入っていける
- 初期RustチームのメンバーであるMatklad(Rust Analyzer創設者)、Brian Anderson(GraydonとともにRust共同創設者) らがTigerBeetleで勤務
- Rustで動的メモリ割り当てを使わないのは「ハードモード」だが、Zigでは容易
Deterministic Simulation TestingとVOPR
DSTの基本概念
-
Deterministic Simulation Testing (DST) は、FoundationDBチーム(現在はApple傘下)が普及させた革新的なテスト手法
- これまでより短い時間で、より安全でバグの少ない分散データベースを開発するために活用
- 分散システムには無限の並行性問題の組み合わせが存在する。メッセージ損失や予測不能なスレッド実行順序など
- 従来の単体テストや統合テストだけでは不十分で、形式検証(formal verification)は高コストで遅い
-
DSTの動作原理
- 特定のタイムラインでシステムが直面しうるほぼすべてのシナリオを 決定論的に実行するシミュレーター
- OS、ネットワーク、ディスク障害やさまざまな遅延のような外部要因も考慮
- 短時間で数年分のテストを提供できる(時間そのものが決定論的になるため
while trueループも可能) - データベース(I/O集約的で、計算集約的ではない)に特に適している
- Jepsenテストは DSTで可能なことの部分集合 にすぎない
TigerBeetleのVOPR
-
VOPR(Viewstamped Operation Replicator)の概要
- 映画WarGamesのWOPRシミュレーターにちなんで名付けられた自社開発のテストクラスター
- ノードがどのようにリーダーを選出するかから、個別の状態やネットワーク障害に至るまで、無数の条件下でTigerBeetleを継続的にテスト
- 単一スレッド上で分散クラスター全体を仮想的にシミュレート 可能
-
VOPRの規模
- 地球上で 最大のDSTクラスター であり、1,000個のCPUコアで稼働
- Hetznerが本当にそれほど多くのコアを望んでいるのか確認する特別なメールを送るほど、異常に大規模
- VOPR-1000は24x7x365で稼働し、本番前にできる限り希少な条件を捕捉
- シミュレーターでは時間が決定論的に抽象化され、約700倍に加速されるため、1日あたり約2,000年分のシミュレーション実行時間 を蓄積
DSTのゲーム化
- TigerBeetleはDSTを ゲームへと変換 し、システムの反応の中でさまざまな障害シナリオをプレイできるようにした
- ゲームは sim.tigerbeetle.com でプレイ可能
- ブラウザー上で実際のVOPRインスタンスを実行し、TigerBeetleをシミュレーション
- WebAssemblyへコンパイル されており、TigerBeetleのエンジニアが実際のシステムを可視化するためにゲームのフロントエンドを構築
TigerStyleとPower of Ten
TigerStyle手法
-
TigerStyleはTigerBeetleの エンジニアリング手法 で、GitHubで公開されている
- 「エンジニアリングと芸術、数字と人間の直観、理性と経験、第一原理と知識、精密さと詩の交差点で進化する集団的なやり取り」
- 映画Tron: Legacyの 「Biodigital Jazz」 という概念を採用。人間とデジタル要素の絡み合い、「Grid」の混沌としながらも構造化された特性、技術の中における人間の潜在力の即興的精神表現
- TigerBeetleでは、科学だけでなく芸術も注ぎ込むコードの精神
-
TigerStyleの影響
- NASAの完璧なコード記述原則である Power of Ten から派生したエンジニアリングおよびコード原則を提示
- 単純さや優雅さのようなテーマから、命名方法のような実践まで扱う
- ResonateやTursoのような他社にも影響を与え始めている
- Lex Fridmanポッドキャストでも議論された
Assertionの使用
-
Power of Tenのルール5: Assertion
- コードの動作に対する期待を、書くのと 同時に 明示的にエンコードするという概念(事後ではない)
- 単一行でブール値として記述: assert(a > b)
-
TigerStyleのassertionルール
- すべての関数引数、戻り値、前提条件、不変条件をassertし、関数あたり平均最低2個のassertion を置く
- assertionが重要で驚くべきものである場合、コメントの代わりにassertionを使う
- プログラム実行前に設計の完全性を確認できるよう、コンパイル時定数間の関係をassert
- 起こるべきことだけでなく、期待しない ネガティブスペースもassert する(興味深いバグが現れうる場所)
性能に対する考え方
-
コードを書くことよりも コードについての推論と設計 のほうが重要
- 性能問題を解決し、巨大な1000倍の勝利を得る最適なタイミングは 設計段階 であり、それは計測やプロファイリングが不可能な正確な時点でもある
-
TigerStyleの性能原則
- 「4つの基本色」(ネットワーク、ストレージ、メモリ、CPU)と「2つの質感」(帯域幅とレイテンシ)について、基本的な概算計算を行う
- コントロールプレーンとデータプレーンの分離、アクセスのバッチ化、ホットループを独立した関数へ切り出してコンパイラ依存を減らすことなど、実践的なヒントを提供
直接体験
- TigerBeetleは、古い形式に現代の研究を適用することで、前例のない 性能と安定性の保証 を提供
- 貸方/借方のネイティブモデリング、分散前提、ストレージ・時計障害耐性、DSTベースの品質保証 を組み合わせた 現代的OLTPエンジン
- システムおよびストレージエンジニアリングをひとつの芸術形式として発展させ、その過程でも楽しさを忘れない
- DSTの巧みな活用 によって、わずか数年でJepsen基準に到達
- 導入は 単一バイナリ で簡単であり、公式サイトの 簡単なインストールスクリプト により、curlコマンドだけですばやく始めて体験できる
6件のコメント
DB がなぜ分散ノードを使わないのかを考えれば、Postgres がなぜ単一ノードなのかを理解できる。
性能より重要なものが何か、考えてみろ
Hacker Newsの意見
TigerBeetleは素晴らしいが、これはTigerBeetleに投資した投資会社が書いた記事だという点は知っておいてほしい 関連リンク
今後数か月、私が書いたこういう投稿が続く予定で、みんながもっと活発に議論してくれると嬉しい。冒頭にディスクレーマーを追加したほうがよいか気になっているが、追加するのは難しくない
その記事は投資会社のサイトに「Portfolio Spotlight」として明確に掲載されているので、期待値はその前提で調整する必要がある
書き方についてあえて言及はしないが、投資会社の文章だということはかなり簡単に分かる
TigerBeetleの正しさへのこだわり、コーディング慣行、超専門特化した方向性のファンではあるが、記事内のいくつかの点は批判したい
マルチノードに関する説明はやや誤解を招く。クラウドネイティブの人たちが何と言おうと、よくチューニングされた単一DBとコネクションプーラーだけでも非常に高いQPSを処理できる。以前の会社では、保守中のミスで全トラフィックを1台のMySQL 8 RDSインスタンスに集中させても、80〜90K QPSを問題なくさばけた。インスタンスも大きくなく、スキーマとクエリ、ProxySQL/MySQLのチューニングをきちんとしていただけだった。ピーク時にはwriterとread replicaの2台で120K QPSも余裕だった
サーバーでnode-local NVMeを使えば、先にCPUの限界に達する可能性が高い
冗長性の問題については、ネットワーク環境向けに設計されたRDBMSなら、結局どれもフェイルオーバーやホットスタンバイ機能を持っている
TigerBeetleのコンセンサスシステムは巧妙で外部依存もないが、大きなrowの処理は試みていない。1MiBのパケットで一度に数千件のトランザクションを処理するなら、従来のRDBMSでは不可能なことを可能にできるかもしれない
これらの批判は彼らの業績を貶める意図ではなく、この製品には今も非常に感銘を受けている
コンセンサスプロトコルの限界を指摘している点こそがまさに核心だ。TigerBeetleはトランザクション専用の処理だけを切り出して扱おうとしているのであって、すべてのOLGP dbを置き換えようとしているわけではない。重要なデータだけを別のトランザクションDBに移せという意図だ。このようなアプローチはTurboPufferにも似たものが見られる
最新のRDBMSが十分高速なのは確かだが、TigerBeetleのユースケースは高コンテンションという特殊な環境だ。実際、複数のトランザクションが1つのアカウントに触れると、クラスタ全体のスループットが劇的に低下することをテストで直接示している。(参考: 関連HNコメント)
JoranとチームのDST、分散システムへの理解、性能テストに関する仕事は本当に気に入っている。特に依存関係を最小化することへの執着は印象的だ(もちろんOSを依存関係と見なすこともできるかもしれない)
ただし、一般的なOLTP(チームではOLGPと呼んでいる)を扱うやり方には、いつも不公平さを感じる。たとえば、金融トランザクションで行ロックだけを使うような低性能なSQLトランザクションだけを例に比較し、まるで50年前のOLTP設計のままのように説明している
公式の性能ページでは、コンテンションを1%までしか下げられないようになっている。StripeのようなところがOLTP DBで1%のコンテンションだとは思わない
コンテンションを予測し、優雅に処理し、極限のトランザクションスループットを実現するシステムは作れる。こうしたシステムはDBをコンテンションから守り、継続的なスケールを可能にする。実際、大規模決済システムのスループット数値は公式の性能比較よりはるかに大きい
マーケティングはこうした点を主に無視し、あらゆる開発者が稚拙なトランザクションばかり投げ込むかのように扱っているが、実際にはほとんどがずっと賢いエンジニアだ。決済業界には「payments engineer」という職種すらある
TigerBeetleはすごいが、他のOLTPを誤解させるようなマーケティングのパターンには違和感がある
賞賛ありがとう
StripeのOLTP DBで1%のコンテンションではないと言っていたが、StripeはMongoDBベースだ。RDBMSとの比較はリンゴとオレンジの比較だ
underlying OSを依存関係と見なせるかについては、完全にin-memoryで動き、kexec中でも持続するシステムを扱った経験がある。syscallsすらできない状況では、OSも十分に依存関係になりうる
ロックベースのトランザクションと、コミット時の条件チェックで処理する最適化方式の例を挙げてもらえると嬉しい
私たちはTigerBeetleを検討したが、以下のような障害があった
私たちはCloudflare Workersを使っているが、TigerBeetleのクライアントアプリがサポートされていない。イシューリンク Cloudflare Containersなら動くかもしれないが、私たちのワークフローはWorkers中心だ
認証(auth)機能がない。サーバー(VPSなど)ではIP制限しかできないが、サーバーレス環境には固定IPがない 関連イシュー
WireguardでIPをECC鍵で認証する方式も解決策になりうる
実際、Cloudflare WorkersやAWS Lambda環境で1000個のワーカーがすべてDBにコネクションを張ると問題が起きる。だから通常はDBの前にプロキシやサービス層を置いて解決する。プロキシはDBへのアクセス方法を知っているので、プライベートネットワークではauthの問題を気にしなくてよい
TigerBeetleのソリューションチームに相談すれば、end-to-end暗号化による論理レベルの認証など、カスタムな解決策を提案してもらえるかもしれない
2025年に認証機能のないDBなんて信じがたい。金融DBなら、少なくとも認証プロキシ/レイヤーを追加する方法のガイドくらいはホームページに載せるべきだ。HTTPを使わないのなら(ドキュメントだけでは明確でない)、HTTPなしでどうやって認証プロキシを付けるのか、誰もが気になるはずだ。その状態でインターネットに露出したら非常に危険だ
「10年でトランザクション量が1000倍以上に増えたのに、使っているDBは20〜30年前のSQLだ。耐えられるのか?」という問いがあったが、十分可能だと思う。
30年前のソフトウェアでも継続的に更新されており、当時しっかり設計された基盤でもある
Joran(TigerBeetle)です。一般的なワークロードでは問題ないが、トランザクション処理ではpower lawコンテンションのためSQLのrow lock問題が生じる(Amdahl's Law参照)。理論上の最大性能限界を計算できるcontention calculatorをホームページに置いてあるので参照してほしい contetion calculator
DNSも1983年に公開され、今なおインターネットの基盤であることを見れば、基礎がしっかりしていれば30年以上前のシステムでも十分耐えうる。SQLは大半のワークロードで十分に優れている
いつでも新しく洗練された技術が、既存の使い尽くされ検証済みの技術より良いとは限らない。ときどきソフトウェアエンジニアは業界で最も「記憶力のない」エンジニアに思える
分散システムで数十個のDBを扱うときは、分散トランザクション(Sagasなど)が必須だ。シングルマシンの状況では、リレーショナルDBは依然として素晴らしい
昔のハードウェアでは性能不足だったが、今は技術が進歩して、むしろより速くうまく動く
FoundationDBもTigerBeetleの議論とかなり多くの共通点がある
コードを書くのが遅いこと、DST、依存性なし、本番での分散前提、楽観ロックで時計ずれを許容すること、Jepsenの苛酷なテスト、新しい言語(Flow)でのテストなど。FDBでも似た問題はすべて解けるし、TigerBeetleはユースケースにより最適化されているのだと思う
FDBが大衆化していない唯一の理由は、よくできたレイヤーがあまりないことだ。ただ、何人かがSQS、DynamoDB、SQLiteレイヤーを別途開発している
FDBが大衆化していない本当の理由はAppleだ。2013年にリリースされ、製品があまりに気に入ったため会社ごと買収し、その後既存ユーザーは全員サービス停止に追い込まれた。独占終了後も信頼は回復していない
FDBチームと協業しながらDST関連の投稿も準備中だ
買収後どうなったのか気にはなる
まさに 'the one true database' だと思う
「なぜすべてのhyperscalerがFDBを使わないのか」と思ってgithub検索したら、結局Apple傘下に入っていた
最近、TigerBeetleの開発スタイルをRustやGoなどに適用してみたが、本当に強く勧めたい
単一のエントリーポイント、ほぼゼロに近い依存関係
ローカルでCI、単一コマンドでテスト/カバレッジ/lintなどを実行
property/snapshot/swarmテストでシミュレーションを導入することに興味を持つようになった
高速/低速の区分、すべてのテストでdeterministicなseedを使う
明示的なupper bound + リソースプール運用で、動的割り当てのコードも理解しやすくなる
TBチームの動画とドキュメントのおかげだ
「本番でassertionを有効にしている」という話が印象的だった
なぜassertionを無効にしてきたのか理解できなかった。運用でassertが失敗したなら、すぐに分かるべきだ(修辞的表現)
歴史的には、assertionを無効化すると性能向上があった。しかし今では、比較を数回増やしたところで大きな影響はない
もともとassertionは開発者によるAPI誤用を防ぐためのチェックだ。ユーザー入力の段階では、適切なエラーメッセージなどを返すビジネスロジックに置き換えるほうが理にかなっている
簡単にはチェックできないものでもassertionにしたくなることがある。たとえば、リストがソート済みであることを確認するようなケースだ
assertion本来の目的はコンパイル/テスト時のチェックだ。本番で使いたいならif文に変えればよい。assertが単なる便利な糖衣構文にすぎないのかを考える必要がある
TBチームにはdouble-entry model(複式簿記)を金融以外のシナリオにももっと広く広めてほしい。株式、コンサートチケットなどでも非常に有用だ。API改善はもう終わったのだから、次は活用法を知らせる段階だ
アナリストとしてSQLはよく使うが、コードを書く開発者ではない。概ね概要説明や性能面の利点は理解している。気になる点がある a) TigerBeetleのデータ構造は実際どんな形なのか? 一般的なテーブル形式ではない気がする b) SQLクエリが使えないなら、どうやって利用するのか c) 複式簿記モデルを株式やチケットなどに適用するとどうなるのか? たとえば会場がチケット1000枚を保有していて1枚売れたら、在庫から現金へ、繰延収益から履行義務へという処理になるのか? それともチケットを売る前は何のエントリもないのか?
Postgresでも似たようなdouble-entryの実装は可能だ
「たいていのチームはコードを急いで書き、テストは苦行にし、依存性を山ほど積む」という話は、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 がものすごく速いという印象を強く与えていますね(笑)
とても興味深いですね。
一般的なサイトよりもアニメーション時間がかなり短く設定されていますね。こういう形でも展開できるんですね...