こんにちは、IT 基盤部第4グループの西崎です。主に DeNA がグローバルに展開するゲームのインフラ管理を担当しています。
本記事は以下構成の第2回であり、 Amazon Aurora DSQL(以下 Aurora DSQL) が Cloud Spanner(以下 Spanner)と比べて何が新しいのかを紹介します。現在判明している Aurora DSQL の新しい特徴とアーキテクチャに焦点を当てることで理解を深め、今後の使い分けを助けるものであり、網羅的な比較ではないことにご注意ください。
- Aurora DSQL は何が新しいのか?(vs. これまでの Aurora 編)
- Aurora DSQL は何が新しいのか?(vs. Spanner 編)
- Aurora DSQL は何が新しいのか?(vs. FoundationDB 編)
Aurora DSQL と Spanner の違いは様々な点を挙げることができますが、今回紹介するのは細かいコンポーネント分割と楽観的排他制御によって、レイテンシ性能とスケール性能に優れることです。
Spanner はどのように一貫性を保つのか
まず Spanner から見ていきましょう。Spanner も分散 SQL と呼ばれますが、その仕組みは Aurora DSQL とは異なります。一言で言うと、Spanner はデータを更新する際にデータを持つ全てのサーバに通信することで整合性を保っています1。
Spanner の内部的な最小構成を図にすると以下になります。2
Spanner 内部のサーバは Spanserver と呼ばれ、これはコンピュート部分とストレージ部分(分散ファイルシステム上のデータ)を持っています。Spanner はデータを zone 間でレプリケーションすることで冗長化して保存するため、同じデータを持つ Spanserver も zone を跨いで存在します。
これらの Spanserver 間では Paxos という仕組みでレプリケーションを行うため、このまとまりは Paxos Group と呼ばれます。Paxos については踏み込みませんが、複数のマシン間で1つの合意を形成する(あるトランザクションをコミットするかどうか、など)仕組みです。これが Spanner がデータを更新する際、対象のデータを保持するサーバ間での通信が必ず発生する理由です。
データが増えると Spanner は自動的に複数の Paxos Group を作成してデータを分散保存します。これは伝統的な RDB やこれまでの Aurora でも行っていたシャーディングを内部的に管理しているということです。
そして更新対象のデータが複数の Paxos Group に存在する場合、Spanner はそれらの Paxos Group 間での二相コミットを行います。この場合にも各 Paxos Group 内での合意形成は行われるため、関係する Paxos Group が増えるとそれだけ多くの通信が発生することになります。地理的に分散した多くのサーバ上のデータを同時に更新するほど、多くの通信が発生することでレイテンシが大きくなる仕組みになっています。
Aurora DSQL は何が新しいのか
Spanner より「4倍高速」
対して Aurora DSQL は re:Invent のキーノートで AWS CEO 自身が語っていたように、「Spanner よりもレイテンシが低い」ことを売りにしています。「4倍」という数字はあくまでキャッチコピーとして捉えるべきですが、この特性はどう実現されているのでしょうか?

出典:https://youtu.be/LY7m5LQliAo?t=3639
書き込みトランザクションが効率化した
以下が Aurora DSQL の内部構造です。 本連載の前回記事 と同じように、左側から来たユーザからの更新クエリの内容が、一番右側の Storage に伝わるまでを表しています。今回注目したいのは書き込みトランザクションに必要な機能が(Adjudicator と Journal に)独立したことで、データを持つ Storage 間の通信が発生しなくなったことです。

出典:https://brooker.co.za/blog/2024/12/05/inside-dsql-writes.html
(以下のコンポーネント説明も前回と同じです)
- Query Processor
- PostgreSQL エンジンが入っているコンピュート部分です
- ユーザからのリクエストを受けて書き込み・読み取り処理を実行します
- Adjudicator
- Query Processor が発行した書き込み処理がデータの一貫性を壊さないか(競合するトランザクションがないか)チェックします
- Journal
- 書き込むデータを受け取って永続化し、非同期で Storage にその内容を伝達します
- Storage
- 実データを保存しています
このように役割分担がされることで、以下の構成のみで書き込みトランザクションがコミットまで完了するようになりました。
コミット内容は Journal に書き込んだ時点で永続化され、自動的に Storage に反映されるため、コミット完了だけであれば Storage への通信は発生しません。複数 Adjudicator 間での通信も行われますが、役割が専門化されることで実際にデータを持っている Storage 間の通信よりも最適化されました3。特に更新対象のデータがストレージ部分で複数のシャード(Spanner では Paxos Group)に跨るようなケースでレイテンシが改善されると考えられます。
楽観的排他制御を採用した
さらに Aurora DSQL は楽観的排他制御を利用しているため事前ロックを取得する分のレイテンシを抑えられます。この利点を最も活かせるのはマルチリージョン構成にした場合で、コミット時まで別リージョンとの通信が発生しないため、レイテンシを大きく抑えることができます。読み取り処理も含めて図にすると以下のようになりますが、1.~ 4. までが1リージョンの中で完結します(Spanner ではデータ読み取り時に Paxos Group の leader サーバへの問い合わせとロック取得が発生します4)。
コミット時には更新対象の状態をグローバルに一致させる必要があることを考えると、これはマルチリージョンに展開したクラスタに対して、それぞれのリージョンから並行した書き込みを理論上最速で実現できる構成です。上記で引用した CEO キーノートでも「READS & WRITES」を含むトランザクションを「multi-Region」で実施した場合と明記されているため、この特性が念頭にあると思われます。
各性能が独立してスケールする
Aurora DSQL はコンポーネントが細かく分割されているため、読み取り・書き込み・ストレージ容量・SQL 実行などの性能がそれぞれ独立にスケールします5。そのため個人の趣味から大企業のアプリケーションまで事実上どのようなサイズにもスケールする一方、専用の設定は必要なく、クラスタ作成のみでスケールを含め全ての機能を利用できます6。
各性能が独立してスケールするという点は、読み取り性能(Query Processor と Storage)、書き込み性能(Query Processor と Adjudicator と Journal)、ストレージ容量(Storage)、SQL 実行性能(Query Processor)がそれぞれ対応するコンポーネントをスケールすることで独立してスケールするためと考えられます7。
対して Spanner の性能は node という単一の設定値で管理されており、どれか1つの性能のみスケールさせたい場合でも node を増やしてその分の料金を支払うしかありません(ストレージも node 当たり 10TB という制限があるため8、あまりリクエストがなくてもデータ容量のため node ごと増やすしかないケースがあります)。そして自動でスケーリングを行いたい場合は OSS として公開されているツールを追加するか、2025年2月に GA されたマネージド機能(エンタープライズ以上のエディションのみ)の利用が必要です9。
Aurora DSQL も詳しい利用条件は判明していないため、この点がどこまで具体的なメリットになるかは現時点では不明です。しかし Aurora DSQL のスケール性能はアーキテクチャとしてメリットを出せる点であり、今回参照している 公式サイト や 開発者ブログ でも特に強調されています。ユーザ側からの管理がなくても柔軟・迅速なスケールが自動的に実現されたり、より細かい単位で利用した分の料金のみ支払えば良くなるなど、ユーザにもメリットとして還元されることを期待しています。
まとめ
Aurora DSQL は Spanner よりレイテンシが低いとされる特徴をメインに紹介しました。その設計からしてAurora DSQL はマルチリージョンに展開した場合に、それぞれのリージョンから互いに競合しない並行した書き込みを低レイテンシで行うことが特に得意な分散 SQL です。
ではシングルリージョンでは使いにくいかというとそんなことはなく、分散 SQL の利点をやはり低レイテンシで享受することができます。また細かく分割されたコンポーネントによるスケール性能のメリットも今後明らかになることが期待されます。
一方で上記の特性を実現させるために楽観的排他制御が使われているという点で、競合しやすい、もしくは長時間かかるトランザクションには向いていないのも事実です。そのような場合は今後も Spanner やこれまでの Aurora を選択すべき場面が多くなるでしょう。
ここまで書いてきましたが、まだ Aurora DSQL は制限の強いプレビュー段階であり、実際の性能やマルチリージョン構成についてはほとんど実機で確かめられていない公開情報からの推測段階でもあります。そもそも同じ PostgreSQL 対応といっても実際にサポートしている機能には違いがあるため、GA 後の選定ではそれぞれのワークロードを前提にした試験を行うようにしてください。
-
単純化して表現しています。トランザクションの完了には全てのサーバとの通信が完了する必要はありません。また本記事の Spanner についての記載は Read-write transaction を想定しています。 https://cloud.google.com/spanner/docs/transactions#read-write_transactions ↩︎
-
2012年発表の論文の内容を元にしています。 https://static.googleusercontent.com/media/research.google.com/ja//archive/spanner-osdi2012.pdf ↩︎
-
https://brooker.co.za/blog/2024/12/05/inside-dsql-writes.html ↩︎
-
https://cloud.google.com/spanner/docs/whitepapers/life-of-reads-and-writes#multi-split_write ↩︎
-
https://aws.amazon.com/jp/rds/aurora/dsql/
https://brooker.co.za/blog/2024/12/04/inside-dsql.html ↩︎ -
読み取り性能と書き込み性能に対応するコンポーネントは、コンポーネント分割の方式が似ている別のデータベースの例から類推しています。
https://www.foundationdb.org/files/fdb-paper.pdf ↩︎ -
https://cloud.google.com/spanner/docs/autoscaling-overview ↩︎
最後まで読んでいただき、ありがとうございます!
この記事をシェアしていただける方はこちらからお願いします。