はじめに
データベースの処理能力を向上させるために、単一データベースを複数データベースに拡張し、更新同期機制(つまり Replication)によって複数データの一貫性を保証します。このようにすれば、データベースの拡張難題はすでに順調に解決されたように見えます
しかし、Replication 方案では、各データベースが完全なデータを保持し、全量データに基づいて追加・削除・更新・検索サービスを提供するため、単一データベースのパフォーマンスボトルネックは依然として存在し、システム拡張性を制限する重要な要因となります
一.単一データベースのパフォーマンスボトルネック
単一マシンのハードウェアリソースは限られているため、単一データベースの処理能力も限られています:
-
容量制限:データ量が単一データベースに収容できないほど大きくなる可能性があります
-
パフォーマンス制限:単一データベースの読み書きパフォーマンスもデータ量の影響を受け、クエリ/更新がますます遅くなります
マシン/データベースを追加するだけでは、単一マシン/単一データベースのパフォーマンス問題を直接解決することはできません。さらにデータベースの境界を打破し、単一データベースを複数データベースに分割する必要があります(単に複数コピーするだけではありません)
P.S.理論上、Web アプリケーション層も同様の問題に直面していますが、1 つの Web サービスが単一マシンにデプロイできないほど庞大になったという話は聞いたことがありません。これはWeb サービスは設計当初から責任分割と結合解除を考慮しているためで、各部分が独立してデプロイ・拡張できるようにするためです。20 年前の SOA(サービス指向アーキテクチャ、マイクロサービスアーキテクチャ(Microservices) などの変種を含む)からそうです
二.パーティショニング(Partitioning)
単一データベースのパフォーマンスがシステム拡張性のボトルネックになるのを避けるために、通常、論理データベース(またはその構成要素、例えばデータテーブル)をそれぞれの独立した部分に分割します。この做法を*パーティショニング(Partitioning)*と呼びます:
A partition is a division of a logical database or its constituent elements into distinct independent parts.
(Partition (database) より引用)
マイクロサービスアーキテクチャでモノリシックアプリケーションを一連の小型サービスに分割するのと同様に、パーティショニングによって単一データベースを一連の(データ規模が)より小さなデータベースに分割し、それぞれが一部のデータを処理し、共同でトラフィックを負担します。主な利点は以下の通りです:
-
拡張性:単一データベースのデータを複数データベースに分割した後、システムの拡張性は単一データベースのパフォーマンスに制限されなくなり、データベース層の「無限」拡張が可能になります
-
パフォーマンス:単一データベースのデータ量が減少し、データ操作がより速くなり、複数データベースの並列操作さえ可能になります
-
セキュリティ:(分割された)機密データに対して、より強力なセキュリティ制御を講じることができます
-
柔軟性:異なるデータベースに対して(例えばデータの重要性に応じて)異なる監視・バックアップ戦略を採用し、コストを削減し、管理効率を向上させることができます。または、不同类型的データに対して異なるストレージサービスを選択できます。例えば、大型バイナリコンテンツを blob ストレージに、より複雑なデータをドキュメントデータベースに保存できます
-
可用性:データを複数のバスケットに分散させることで、単一障害点を回避でき、単一データベースの障害は一部のデータのみに影響します
具体的には、3 つの分割戦略があります:
-
水平パーティショニング(Horizontal partitioning、Sharding とも呼ぶ):行ごとに分割し、異なる行を異なるテーブルに配置
-
垂直パーティショニング(Vertical partitioning):列ごとに分割し、一部の列を他のテーブルに配置
-
機能別パーティショニング(Functional partitioning、Federation とも呼ぶことがある):ビジネス機能ごとに分割し、ビジネス領域内で同じ境界付けられたコンテキスト(Bounded Context)に属するデータを一緒に配置
もちろん、これら 3 つの戦略は矛盾せず、組み合わせて使用できます
P.S.ドメイン駆動設計(Domain-Driven Design)および境界付けられたコンテキストの詳細情報は、分散データ管理(Decentralized Data Management) を参照
三.水平パーティショニング

水平パーティショニング、つまり*シャーディング(Sharding)*です。各シャード(shard)は元データの一部であり、共同で完全なデータセットを構成します:
A database shard is a horizontal partition of data in a database or search engine. Each individual partition (or server) acts as the single source for this subset of data.
(Shard (database architecture) より引用)
垂直パーティショニングと比較して、水平パーティショニングの最大の特徴はスキーマが保持不变であることです:
Each partition is a separate data store, but all partitions have the same schema.
1 つのテーブルを横向きに数回切り、いくつかの小さなテーブルに分割するようなもので、それらのテーブル構造(フィールドなど)は完全に一致します
この横向き分割は、単一データベースが保存する必要のあるデータ量、および負担する必要のあるトラフィック/操作を削減し、他方で、リソース競合(contention)を削減し、パフォーマンス向上に役立ちます
shard key の選択
具体的な操作では、shard key をどのように選択するか(どのフィールドのどの特徴でシャーディングするか)が鍵であり、負荷が各シャードに均等に分散されることを可能な限り保証します
均等とは、各シャードのデータ量が均等であることを要求するわけではなく、トラフィックを均等に分割することが重点です(一部のシャードはデータ量が非常に大きいかもしれませんが、アクセス量は非常に低い可能性があります)
同時に「ホットスポット」の発生を回避する必要があります。例えば、ユーザー情報を姓のイニシャルでシャーディングするのは実際には均等ではありません。一部の文字はより一般的だからです。この場合、ユーザー ID のハッシュ値でシャーディングする方がより均等になる可能性があります
四.垂直パーティショニング
もう 1 つの分割方法は垂直パーティショニングで、一部の列(フィールド)を他のテーブルに分割します:

I/O を削減し、パフォーマンスコストを低減するためによく使用されます。例えば、使用頻度に応じて頻繁に使用されるフィールドとあまり使用されないフィールドを分離します
水平パーティショニングと比較して、垂直パーティショニングの重要な利点は情報をより細かく分割し、さらにいくつかの针对性的な最適化を可能にすることです。例えば、あまり変化しないデータを分割してキャッシュに投入したり、写真などの大型バイナリコンテンツを分割して単独で保存したり、一部の機密データに対して针对性的なセキュリティ制御を講じたりできます。他方で、細粒度のデータ分割はいくつかの並行アクセスを消除し、並行アクセス量を低減できます
五.機能別パーティショニング
さらに、具体的なアプリケーションシナリオに応じて、ビジネス機能ごとに分割することもできます:

無関係なデータを除外し(密接に関連するデータを一緒に配置)、データ分離を強化し、データアクセスパフォーマンスを向上させるのに役立ちます。例えば、顧客情報と商品在庫情報を分離します
六.パーティショニングの代償
単一データベースを複数データベースに分割すると、データベースの拡張性難題を解決できますが、いくつかの新しい問題も引き起こします:
-
テーブル結合クエリが遅い:パーティション横断 join を可能な限り回避する、または並列クエリを検討
-
全テーブルクエリが遅い:全量データをスキャンする必要があるクエリ操作の場合、並列最適化があっても遅いです。垂直パーティショニング、機能別パーティショニングによってターゲットパーティションを定位し、全テーブルクエリを回避できます。水平パーティショニングの場合、アプリケーション層でマッピングテーブルを維持し、パーティション定位を高速化できます
-
トランザクション操作をサポートしない:トランザクション操作をアプリケーション層に委ねて処理
-
負荷不均衡によりパーティション効果が大幅に低下:監視を追加し、分析予測に応じて定期的に調整することを検討
確かに、これらの問題の一部には非常に美しい解決策はありません。実際のアプリケーションでは、特定のシナリオに向けたトレードオフがほとんどです
参考資料
-
[How Sharding Works](https://medium.com/ @jeeyoungk/how-sharding-works-b4dec46b3f6)
コメントはまだありません