プログラミング
スケールするのか?
Ok, but Does It Scale? (spacetimedb.com)
要約
Spacetimeデータベースの拡張性に関する疑問に答える記事です。拡張性には計算能力、ストレージ、ネットワークの3つの次元があり、Spacetimeは特にストレージの水平拡張に強みを持っています。しかし、すべての計算やネットワーク処理が水平拡張できるわけではなく、Spacetimeは競合するトランザクション下でも高いパフォーマンスを発揮し、並列化可能なOLTPワークロードの拡張を容易にするツールを提供します。
全文翻訳
これはおそらく、Spacetimeについて最もよく聞かれる質問です。単純な質問のように思えますが、単純な答えがあるはずです。拡張性は複雑なトピックであり、しばしば細部に悪魔が宿ります。一方で、ブログ記事で最初の原則から拡張性を理解できないほど複雑でもありません。まず、一般的な拡張性を探求し、次に「Spacetimeはどのように拡張するのか?」という質問に答えます。
TL;DRを知りたい場合: 拡張性には、計算、ストレージ、ネットワークの3つの次元があります。ストレージの水平拡張は比較的簡単で、2026年10月31日に出荷されます。しかし、すべてのネットワークおよび計算が水平拡張できるわけではありません。一般的な水平拡張を謳うOLTPデータベースは、トランザクションごとに巨大なオーバーヘッドを支払い、競合するトランザクションに直面すると極めてパフォーマンスが悪くなります。Spacetimeは競合下で高いパフォーマンスを提供し、並列化可能なOLTPワークロードを簡単に拡張するためのツールを提供します。
注意
注: この記事では CockroachDB について多く言及しています。CockroachDB は、Spanner や Aurora DSQL を含む、一般用途の水平拡張可能な RDBMS のほぼすべてを rough stand-in として使用しています。これらの技術に関するいくつかの問題について言及していますが、それらはすべて信じられないほど印象的な工学的な偉業です。
拡張性
直感的に、誰もが「拡張する」ことの意味を理解しています。それは、より多くを行うことができることを意味します。それは、需要に追いつくことを意味します。それは、数十億のリクエスト、または「無限」のリクエスト、または無限のデータ量、または無限の顧客数、またはソフトウェアを書き直すことなく、年間 10 倍または 100 倍でアプリを成長させる能力を処理することを意味します。特に、ほとんどの人がシステムが拡張可能だと言うとき、彼らはそれが特に水平拡張可能かどうかについて話しているのだと思います。一方、垂直拡張性は単一のコンピュータでより多くを行うことを意味しますが、水平拡張性はより多くのコンピュータでより多くを行う能力です。コンピュータの数を倍増させると、ほぼ 2 倍の作業ができる場合、計算は水平拡張されます。結局のところ、単一のコンピュータはそれほど大きく高速にしかできませんが、理論的には購入できるコンピュータの数に制限はありません。その考え方には非常に満足感があるので、それが誰もが探している特性です。
注意
注: 「より多くのコンピュータでより多くを行う」という定義は、すべての水平拡張可能なシステムが分散システムでなければならないことを意味します。しかし、それは分散システムの唯一の目的が水平拡張性であるとは限りません。例えば、分散状態機械レプリケーションは、信頼性を目的として、拡張性ではなく、多くのコンピュータで同じ計算を冗長に行うように設計されています。これについては、後述の Spacetime のセクションで詳しく説明します。
「水平拡張できるか?」という質問は、不十分です。より良い質問は、「どのような点で水平拡張できるか?」ということです。なぜなら、拡張性の次元は実際には 3 つあり、かなり独立しているからです。
計算: 処理できるトランザクションの数
ストレージ: 保存できるデータの量
ネットワーク: サポートできる接続数と帯域幅
注意
ちなみに、これらは 1.0 の発表基調講演で言及した、まさに 3 つの「基盤となる要素」です。私が言いたいことを見るために、広く PostgreSQL 互換インターフェイスを公開しているが、根本的に異なるアーキテクチャを持ついくつかのデータベースシステムを見てみましょう。
例えば:
Postgres は、ほとんどの場合、単一ノードのデータベースです。Postgres は、計算、ストレージ、またはネットワークを水平拡張しません。もちろん、多くの Postgres インスタンスをデプロイすることで Postgres を水平拡張できますが、Postgres コードの範囲では、それらの他のインスタンスをほとんど認識していません。唯一の例外はリードレプリカで、リーダーをレプリカに手動でリダイレクトできます。これはネットワークと計算の両方を拡張するのに役立ちますが、読み取り後の書き込みの一貫性とパフォーマンスに関する注意点があります。Postgres 自体には、プライマリのクラスタという概念はなく、それらを横断するトランザクションやクエリを実行したり、適切なものにルーティングしたりすることはできません。もちろん、これを行うソフトウェアを書くことはできますし、人々が Postgres を水平拡張する方法はこれです。しかし、その方法は読者の演習として残されています。
Neon は、Postgres の変更されたバリアントであり、ストレージを水平拡張します。Neon テーブルは、データアクセスを高速かつ効率的にするためにローカルページキャッシュ構造を持つオブジェクトストレージによってバックアップされています。ページアクセスレイテンシはキャッシュミスで高くなる可能性がありますが、このアーキテクチャにより Neon データベースは実質的に無限のストレージを持つことができます。しかし、Neon は計算とネットワークを自動的に水平拡張しません。Postgres と同様に、すべての書き込みトランザクションは 1 つのプライマリを経由する必要があります。ただし、Postgres バリアントとして、Neon は読み取りワークロードの計算とネットワークを水平拡張するためのリードレプリカもサポートしていますが、これには同様の一貫性に関する注意点があります。自動計算拡張がなくても、ストレージの水平拡張は大きなメリットです。ユーザーがそれほど多くない小さな Web アプリでも、原理的には多くのストレージを使用できます。
CockroachDB (および Spanner) は、原理的にはストレージを水平拡張します。各テーブルのデータをクラスタ全体に分散させることで、テーブルの一部である「範囲」が各マシンに格納され、通常は 2 つの他のマシンにレプリケートされます。ライターがすべて同じ範囲を変更しようとしない限り、ネットワークも水平拡張できます。対称的なアーキテクチャを備えており、どのノードでも読み取りと書き込みの両方の SQL リクエストを処理できます。最後に、計算がクリーンに並列化できる場合 (例: 分析または無関係なキーへの書き込み)、計算も水平拡張できます。接続したノードはクエリプランを計算して結果を返しますが、読み取りおよび書き込み操作は、範囲に基づいてクラスタ全体にわたる分散トランザクションの一部として実行されます。
聖杯を見つけられるか?
CockroachDB が 3 つの次元すべてで拡張できる場合、Postgres と Neon よりもすべての点で優れているはずですよね? CAP 定理[1] や原子時計について特別なことをしているのでしょうか? 残念ながら、ここには魔法はありません。CockroachDB は現代の驚異であり、特定の計算を水平拡張しますが、すべての計算が水平拡張できるわけではありません。水平拡張性は、実際には並列コンピューティングの問題です。計算を異なるコンピュータが同時に実行できる部分に分割できますか? 答えはしばしばノーであり、CockroachDB の問題は、データ競合により一度に 1 つずつ更新しなければならない場合でも、水平拡張性の巨大な調整コストを支払うことです。CockroachDB が水平拡張性で得るものは、垂直拡張性で失い、さらにそれ以上です。醜い真実は、より多くのコンピュータでより多くを行うのではなく、水平拡張性はしばしばより多くのコンピュータでより少なく行うことを意味することです。概念的には、1 台のコンピュータが 1 ミリ秒で行えることを、10 台のコンピュータが 100 ミリ秒で行えるということです。
CockroachDB の水平拡張性のアプローチには、主に 2 つの問題があります。
各トランザクションに関与するデータは、単一のマシン上に共存することはほとんどありません。
どのトランザクションも範囲への排他的アクセス権を持たないため、すべてのトランザクションは分散同時実行制御オーバーヘッドを支払い、競合するトランザクションは待機、中止、または再試行する必要があります。
最初の問題は、クラスタ全体にデータの所有権を均等に分散させることによって引き起こされます。データがクラスタ全体に分散されている場合、実質的にすべてのトランザクションでネットワークリクエストを行う必要があります。シャーディングは不便に聞こえることがありますが、ほとんどのトランザクションが単一のシャード内で操作される場合、より良いパフォーマンスを提供できます。また、Neon の設計は、ホットページを同じマシンにキャッシュするため、多くのワークロードでこの同じ問題に悩まされないことに注意してください。
注: Spanner は、関連テーブルを共存させることができるように「テーブルインターリーブ」でこの問題の一部を解決します。これにより、単純な ca のパフォーマンスが劇的に向上します。