近年のWebサービスやクラウドシステムでは、複数のサーバーに処理を分散させる構成が一般的になっています。そこで疑問になりやすいのが、「アプリケーションサーバーを分散させた場合、データベースも特別な分散型DBにしなければならないのか」という点です。
結論からいうと、分散型のサーバー構成だからといって、必ず分散データベースを採用するわけではありません。PostgreSQLやMySQLのような一般的なRDBを中心に据える構成もあれば、DynamoDBやCassandraのようなNoSQL、CockroachDBなどの分散SQLを使う構成もあります。
重要なのは「サーバーが何台あるか」ではなく、データ量、アクセス数、整合性、可用性、地理的な分散、運用コストなどの要件です。ここでは現代の分散システムで使われるDBを、アーキテクチャの違いから整理します。
まず「分散型サーバー」と「分散データベース」は別の話
Webシステムでは、ロードバランサーの後ろに複数台のWeb・アプリケーションサーバーを置くことがあります。このようにアプリ側を水平スケールさせても、DBは1つのプライマリを中心としたRDBという構成が可能です。
例えば「ロードバランサー → アプリサーバー複数台 → PostgreSQL」という構成です。PostgreSQLにはストリーミングレプリケーションなど高可用性を構築するための仕組みがあり、複数サーバーで同じデータを扱う構成を作れます。PostgreSQL公式ドキュメントでも、高可用性、負荷分散、レプリケーション、フェイルオーバーなどが解説されています。[参照] PostgreSQL公式ドキュメント
つまり「アプリケーションが分散している=DBも最初から特殊な分散DB」という理解ではありません。むしろ一般的な規模では、実績のあるRDBを利用しながら必要に応じてレプリカやキャッシュなどを追加する設計も有力です。
PostgreSQL・MySQLなどのRDBは現在でも重要
分散システムという言葉からNoSQLを連想しやすいものの、ユーザー、商品、注文、契約、決済など、データ同士の関係とトランザクションが重要なサービスではRDBが適しています。
例えばECサイトで「注文を作成する」「在庫を減らす」「支払い状態を記録する」といった処理では、途中だけ成功すると困ります。このようなデータをSQLとトランザクションで扱えることは大きな利点です。
規模が大きくなった場合も、読み取り専用レプリカ、キャッシュ、テーブルのパーティショニングなどを組み合わせて対応できます。そのため、「古いシステム=RDB、現代的な分散システム=NoSQL」という単純な分類ではありません。
DynamoDBのような分散NoSQLが向いているケース
大量のアクセスを水平に分散させたいシステムでは、Amazon DynamoDBのようなマネージドNoSQLが選択肢になります。AWSによると、DynamoDBはデータとトラフィックを必要な数のサーバーへ自動的に分散する仕組みを持つNoSQLデータベースです。[参照] Amazon DynamoDB公式ドキュメント
DynamoDBではパーティションキーが特に重要です。データはパーティションに格納され、パーティションキーを基に配置先が決まります。AWS側がパーティション管理を行うため、利用者がDBサーバーを1台ずつ管理する必要はありません。[参照] DynamoDBのパーティションとデータ分散
一方で、RDBと同じ感覚でテーブルを作って後から自由に複雑な検索を行う設計には向きません。AWSもDynamoDBの設計では、システムが必要とするアクセスパターンをあらかじめ理解することが重要だと説明しています。[参照] DynamoDBのNoSQL設計
Cassandraは多数のノードへデータを分散するNoSQL
Apache Cassandraも代表的な分散NoSQLデータベースです。Cassandraは分散型のワイドカラム型NoSQLとして設計され、データをパーティションとしてクラスタ内のノードへ配置します。[参照] Apache Cassandra公式ドキュメント
複数のレプリカを持たせられるため、一部ノードに障害が起きても別のレプリカからデータを利用できる構成を作れます。またノードを追加して処理能力を拡張するスケールアウトを重視した設計です。
ただし、CassandraにはRDBとは異なるデータモデリングや整合性の考え方があります。公式ドキュメントでは、Cassandraは基本的に結果整合性を採用しつつ、用途に応じた整合性制御や軽量トランザクションの仕組みも提供しています。[参照] Cassandraの整合性と可用性
近年は「分散SQL」という選択肢もある
NoSQLは水平スケールに強い一方、「SQLやトランザクションを使いながらデータベース自体も分散させたい」という需要があります。そこで登場したカテゴリーの一つがDistributed SQL(分散SQL)です。
代表例としてCockroachDBがあります。CockroachDBはSQLインターフェースを提供しながら、内部ではデータを分散・複製するアーキテクチャを採用しています。CockroachDBの解説では、SQL処理を下位の分散・複製されたトランザクショナルなKey-Valueストアへ変換する構造が説明されています。[参照] CockroachDBの分散SQLアーキテクチャ
このタイプは、複数ノードや複数リージョンへデータを配置しながらSQLや強い整合性を利用したいシステムで候補になります。ただし、ネットワーク越しの合意形成や分散トランザクションにはコストがあるため、「分散SQLなら常に普通のRDBより速い」という意味ではありません。
1つのサービスで複数種類のDBを使うこともある
現代の大規模システムでは、すべてのデータを1種類のDBへ保存する必要はありません。データの性質によって保存先を使い分ける「Polyglot Persistence」という考え方もあります。
例えば、ユーザーや注文など整合性が重要な情報はPostgreSQL、非常に大量のKey-ValueデータはDynamoDB、キャッシュはRedis、全文検索は検索エンジン、といった構成が考えられます。
ただしDBを増やすほど、バックアップ、監視、障害対応、データ同期、権限管理などの運用は複雑になります。小規模なシステムで「最近の流行だから」という理由だけで複数のDBを導入するメリットは必ずしもありません。
CAP定理を知ると分散DBの違いが理解しやすい
分散データベースを理解するときによく登場するのがCAP定理です。ネットワーク分断が起こり得る分散システムでは、整合性(Consistency)、可用性(Availability)、分断耐性(Partition tolerance)の関係を考える必要があります。
実際の製品は単純に「CP型」「AP型」と一言で片付けられない機能や設定を持つことも多いものの、なぜ分散DBによって読み書きの挙動や整合性保証が違うのかを理解する入口になります。
例えば「障害時にもできるだけ書き込みを受け付けたい」のか、「多少利用できなくなっても矛盾した結果を返したくない」のかによって、設計上重視するものが変わります。
結局どのDBを選べばよいのか
DBは「分散型だからこれ」と決めるのではなく、システム要件から逆算します。小~中規模の一般的なWebサービスで複雑なトランザクションが必要なら、まずPostgreSQLやMySQLなどのRDBを検討するのは現在でも合理的です。
非常に大きなKey-Value系ワークロードをクラウド側に任せたいならDynamoDB、大量の書き込みや複数ノード・データセンターへの分散を重視するならCassandra、SQLを維持しながらDBそのものを水平・地理的に分散させたいならCockroachDBなどの分散SQLが候補になります。
| 要件 | 候補例 |
|---|---|
| 一般的なWebアプリ・トランザクション重視 | PostgreSQL、MySQLなど |
| 大量のKey-Valueアクセス | DynamoDBなど |
| 多数ノード・大量書き込み・高可用性 | Cassandraなど |
| SQL+水平分散+強い整合性 | CockroachDBなどの分散SQL |
| 高速な一時データ・キャッシュ | Redisなど |
「一番新しいDB」を選ぶより、「必要な整合性・クエリ・スケール・障害耐性を満たす最も単純な構成」を選ぶことが重要です。
まとめ:分散型サーバーでもDBは用途によって大きく異なる
近年の分散型システムで使われるDBは一種類ではありません。アプリサーバーだけを分散させてPostgreSQLなどのRDBを利用する構成もあれば、DynamoDBやCassandraのような分散NoSQL、CockroachDBのような分散SQLを採用する構成もあります。
特に重要なのは、アプリケーションサーバーの分散とデータベースの分散を別々に考えることです。Webサーバーが100台あるからDBも100台必要、という関係ではありません。
DBを選定するときは、データ量だけでなく、読み書きの比率、必要なトランザクション、整合性、可用性、アクセスパターン、リージョン構成、運用できる人員とコストまで含めて検討します。まずRDBで十分なのかを確認し、明確なスケーラビリティや地理分散の要件が出てきた段階でNoSQLや分散SQLを検討すると、過度に複雑な構成を避けやすくなります。


コメント