
2025/12/21 7:12
より多くのデータベースはシングルスレッドであるべきです。
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
(欠落している要素を組み込む)**
要約
著者は、トランザクションデータベースは従来のマルチスレッドシャードではなく 単一スレッドで積極的にシャーディングされたシステム として構築すべきだと主張しています。各シャードに専用の書き込みスレッド(「シャードごとの単一ライター」)を割り当てることで、書き込み競合が排除され、高価な再試行やデッドロックなしでシリアライズ可能なトランザクションを実現できます。
従来の SQL トランザクションモード(READ COMMITTED, REPEATABLE READ, SERIALIZABLE)は小規模ではうまく機能しますが、重負荷下でロック競合、高い再試行率、不確定な失敗に悩まされます。提案モデルはこれらのボトルネックを取り除きます。
実際のトレードオフ:
初日からシャーディングすることで、複雑なクロスシャードクエリ、マイグレーション、トランザクション調整の必要性がなくなります。しかし、カウンタ、AUTO_INCREMENT カラム、シャード間での外部キー検証など、グローバル順序に依存する機能には制約を課します。
実現可能性の証拠:
既存システムはすでにこのアプローチを採用しています。ScyllaDB と VoltDB はシャードごとにコアを割り当てる設計であり、Cloudflare Workers や Rivet のようなアクターモデルプラットフォームも同様の「シャードあたり単一スレッド」概念を使用しています。
将来像:
著者は、Postgres 互換のデータベースが シャーディングされ、シャードごとに単一スレッドで完全にシリアライズ可能 であり、平均的なウェブ開発者でも利用できるようになり、規模拡大時に予測可能な性能を提供することを想像しています。
影響:
利点には概念の単純さ、デッドロックの排除、完全な水平スケーラビリティ、高いスレッドあたりのスループット、および予測可能な遅延が含まれます。このアーキテクチャは開発者にとってシステム設計を簡素化し、企業にとって運用複雑性を低減させ、データベース業界全体をシャード中心の設計へと影響する可能性があります。
本文
タイトル:攻撃的にシャーディングされた単一スレッド型データベースが最適解になる理由
昨晩、X(旧Twitter)で「ほとんどのトランザクション系データベースは単一スレッドで、かつ積極的にシャーディングすべきだ」と投稿しました。予想以上に注目を浴びたので、もう少し詳しく説明します。
「万能な解決策は存在しません。しかし、攻撃的にシャーディングされた単一スレッド型データベースが、実際にはあなたの期待よりも頻繁に最適であることをご納得いただけると信じています。たとえ汎用的なB2B SaaSアプリを構築しているだけでも同様です。」
現状
従来のSQLデータベースは行単位で読み書きを行い、他のライターが待つようにロックできます。
PostgreSQLでは次の3種類のトランザクションモードがあります。
| モード | 保証内容 |
|---|---|
| READ COMMITTED(デフォルト) | 現在の状態を読み取り、書き込みは失敗しない |
| REPEATABLE READ | トランザクション開始時点でスナップショットを取得。以降に行が変更されると書き込みは中止 |
| SERIALIZABLE | REPEATABLE READ と同様だが、依存関係のある任意の行変更でも中止 |
問題点:
- 起動時 – トランザクションが本当にシリアライズ可能であることをコンパイル時に保証できない。
- スケール – いずれも書き込みロックが必要。高負荷時にはデッドロックや再試行率の増加。
- 予測性 – 本番環境でのレースコンディションはデバッグが難しい。
- スループット – ロック競合がDBロードの最大30%を消費し、トラフィック増加に伴い失敗率が上昇。
多くのスタックでは、サーバーレスコンピュートは水平に無制限に拡張できる一方で、データベースがスケーリングのボトルネックになるケースが少なくありません。
実務的現実
多くの企業は「ユーザーが増えてから対策を講じる」といった形でこれらの問題を放置します。
もっとシンプルなアプローチがあるとしたら?
1. 単一ライター型データベース
核心的課題は競合する書き込みです。もし全トランザクションが書き込まないのであれば、
SERIALIZABLE READ ONLY DEFERRABLE を使えば十分です。
アイディア:各シャードに対してグローバルロックを設け、単一ライターのみ許可する。SQLite が行っている手法そのものです。
- メリット:完璧な順序保証、デッドロックなし
- デメリット:
- 単一ライターはスループットを制限
- ロックオーバーヘッド(ファイルシステムレベルのロック)
- ライターが停滞すると他全員も停滞
2. ライタ―のシャーディング
単一ライターが限界に達する場合、水平にシャードします。
- データベースを多数の小さなシャードへ分割
- 各シャードは独自の 単一 ライタースレッドを持つ
- 読み取りはコアごとに並列化可能
メリット
| 機能 | 利点 |
|---|---|
| シャード単位でのシリアライズ | 再試行不要(失敗時のみ) |
| デッドロックなし | シンプルな概念モデル |
| 水平スケーリング | ノードを追加して容量拡張 |
| 高いスレッド単位スループット | データはライターが所有、スレッド間同期不要 |
課題
- クロスシャードクエリ(複雑な結合や集計)が難しい
- シャード横断トランザクションの実装が困難(2フェーズコミットやサガが必要)
- マイグレーションは各シャードを個別に扱う必要
3. 実践的考慮点
| 問題 | 一般的な影響 | 対策 |
|---|---|---|
| カウンタ/オートインクリメント | シャード横断でサポート不可 | UUIDやタイムスタンプIDを使用 |
| DBレベル制約 | クロスシャード外部キーは強制できない | アプリケーション側で検証 |
| クロスシャード結合 | 遅く、複雑 | OLAPリプレイヤーに集計結果をマテリアライズ |
| マイグレーション(ダウンタイム vs 無停止) | 各シャードでトランザクショナルコミットが必要 | ツールを用意し、すべてのシャードで一括コミット |
4. 既存システム例
- ScyllaDB – コアごとにシャーディングされたアーキテクチャ
- VoltDB – 同様のモデル
- Cloudflare Workers / Rivet – アクターモデルを取り入れたデータベース
これらは大規模ケース向けですが、同じ原則が小規模プロジェクトにも適用できます。
5. なぜ検討すべきか
- 予測可能性 – 隠れたレース条件がない
- シンプルさ – 各シャードのトランザクションは設計上シリアライズ済み
- スケーラビリティ – 水平拡張が容易
- パフォーマンス – ロック競合と再試行を排除
もちろん、クロスシャード結合の制限やマイグレーションの複雑さなど一部トレードオフはあります。しかし、多くのB2B SaaSアプリではそのメリットがコストを上回ります。
結論
「データベースを初日からシャーディングし、マイグレーションやクロスシャードロジックを扱うツールに投資できる」なら、攻撃的にシャーディングされた単一スレッド型アーキテクチャは非常に強力で予測可能な基盤となります。
特に従来のロックメカニズムによるオーバーヘッドなしにシリアライズ可能なトランザクションを実現したい場合、この手法は最適解になるでしょう。