データのパーティション分割のガイダンス
多くの大規模なソリューションでは、データは個別に管理およびアクセスできる パーティション に分割されています。 パーティション分割により、スケーラビリティの向上、競合の低減、パフォーマンスの最適化を実現できます。 また、使用パターンに基づいてデータを分割するメカニズムも提供できます。 たとえば、古いデータを廉価なデータ ストレージにアーカイブできます。
ただし、悪影響を最小限に抑えながら利点を最大化するには、パーティション分割戦略を慎重に選択する必要があります。
注
この記事では、 パーティション分割 という用語は、データを個別のデータ ストアに物理的に分割するプロセスを意味します。 SQL Server テーブルのパーティション分割と同じではありません。
データをパーティション分割する理由
スケーラビリティを向上させます。 1 つのデータベース システムをスケールアップすると、最終的に物理ハードウェアの制限に達します。 データを複数のパーティションに分割し、それぞれが個別のサーバーでホストされている場合は、ほぼ無期限にシステムをスケールアウトできます。
パフォーマンスの向上。 各パーティションに対するデータ アクセス操作は、より少量のデータに対して行われます。 正しく完了すると、パーティション分割によってシステムの効率が向上する可能性があります。 複数のパーティションに影響を与える操作は、並列で実行できます。
セキュリティを強化します。 場合によっては、機密データと非センシティブ データを異なるパーティションに分離し、機密データに異なるセキュリティ制御を適用できます。
運用上の柔軟性を提供します。 パーティション分割により、操作の微調整、管理効率の最大化、コストの最小化を実現する多くの機会が提供されます。 たとえば、各パーティション内のデータの重要性に基づいて、管理、監視、バックアップと復元、その他の管理タスクのさまざまな戦略を定義できます。
データ ストアを使用パターンと一致させます。 パーティション分割を使用すると、コストとデータ ストアが提供する組み込み機能に基づいて、各パーティションを異なる種類のデータ ストアにデプロイできます。 たとえば、大きなバイナリ データは BLOB ストレージに格納できますが、より構造化されたデータはドキュメント データベースに保持できます。 詳細については、「 適切なデータ ストアの選択」を参照してください。
可用性を向上させます。 複数のサーバー間でデータを分離すると、単一障害点を回避できます。 1 つのインスタンスが失敗した場合、そのパーティション内のデータのみが使用できなくなります。 他のパーティションに対する操作は続行できます。 マネージド サービスとしてのプラットフォーム (PaaS) データ ストアの場合、これらのサービスは組み込みの冗長性で設計されているため、この考慮事項はあまり関係ありません。
パーティションの設計
データのパーティション分割には、次の 3 つの一般的な方法があります。
水平パーティション分割 (シャー ディングと呼ばれることがよくあります)。 この方法では、各パーティションは個別のデータ ストアですが、すべてのパーティションに同じスキーマがあります。 各パーティションは シャード と呼ばれ、特定の顧客セットのすべての注文など、データの特定のサブセットを保持します。
垂直パーティション分割。 この戦略では、各パーティションは、データ ストア内の項目のフィールドのサブセットを保持します。 フィールドは、使用パターンに応じて分割されます。 たとえば、頻繁にアクセスされるフィールドは、1 つの垂直パーティションに配置され、アクセス頻度の低いフィールドが別のパーティションに配置される場合があります。
機能パーティション分割。 この戦略では、システム内の境界付けられた各コンテキストで使用される方法に従ってデータが集計されます。 たとえば、eコマース システムでは請求書データが 1 つのパーティションに格納され、製品在庫データが別のパーティションに格納される場合があります。
これらの戦略は組み合わせることができます。パーティション分割スキームを設計するときは、それらすべてを考慮することをお勧めします。 たとえば、データをシャードに分割し、垂直パーティション分割を使用して、各シャード内のデータをさらに分割することができます。
水平パーティション分割 (シャーディング)
図 1 は、水平方向のパーティション分割またはシャーディングを示しています。 この例では、プロダクト インベントリ データは、プロダクト キーに基づいてシャードに分割されます。 各シャードは、アルファベット順に編成された連続したシャード キーの範囲 (A から G、H- Z) のデータを保持します。 シャーディングにより、負荷がより多くのコンピューターに分散されるため、競合が軽減され、パフォーマンスが向上します。
図 1 - パーティション キーに基づくデータの水平方向のパーティション分割 (シャーディング)
最も重要な要素は、シャーディング キーの選択です。 システムの稼働後にキーを変更することは困難な場合があります。 キーは、ワークロードをシャード全体にできるだけ均等に分散させるために、データがパーティション分割されていることを確認する必要があります。
シャードが同じサイズである必要はありません。 要求の数のバランスを取る方が重要です。 シャードの中には非常に大きいものもありますが、各項目のアクセス操作の数は少ない場合があります。 他のシャードは小さい場合がありますが、各項目にアクセスする頻度は大幅に高くなります。 また、1 つのシャードがデータ ストアの (容量と処理リソースの観点から) スケール制限を超えないようにすることも重要です。
パフォーマンスと可用性に影響する可能性がある "ホット" パーティションの作成は避けてください。 たとえば、顧客の名前の最初の文字を使用すると、一部の文字がより一般的であるため、分布が不均衡になります。 代わりに、顧客識別子のハッシュを使用して、パーティション間でより均等にデータを分散します。
大きなシャードを分割したり、小さなシャードをより大きなパーティションに結合したり、スキーマを変更したりする将来の要件を最小限に抑えるシャーディング キーを選択します。 これらの操作は非常に時間がかかる場合があり、実行中に 1 つ以上のシャードをオフラインにする必要があります。
シャードがレプリケートされる場合は、一部のレプリカをオンラインにしたまま、他のレプリカが分割、マージ、または再構成される可能性があります。 ただし、再構成中に実行できる操作を制限する必要がある場合があります。 たとえば、レプリカ内のデータは、データの不整合を防ぐために読み取り専用としてマークされる場合があります。
水平パーティション分割の詳細については、「 シャーディング パターン」を参照してください。
垂直パーティション分割
垂直パーティション分割の最も一般的な用途は、頻繁にアクセスされる項目のフェッチに関連する I/O とパフォーマンスのコストを削減することです。 図 2 は、垂直パーティション分割の例を示しています。 この例では、項目のさまざまなプロパティが異なるパーティションに格納されます。 1 つのパーティションには、製品名、説明、価格など、より頻繁にアクセスされるデータが保持されます。 別のパーティションには、在庫データ (在庫数と最後に並べ替えられた日付) が保持されます。
図 2 - 使用パターンによるデータの垂直方向のパーティション分割。
この例では、アプリケーションは、製品の詳細を顧客に表示するときに、製品名、説明、および価格を定期的に照会します。 これらの 2 つの項目は一般的に一緒に使用されるため、在庫数と最終注文日は別のパーティションに保持されます。
垂直パーティション分割のその他の利点:
比較的低速なデータ (製品名、説明、価格) は、より動的なデータ (在庫レベルと最終注文日) から分離できます。 データの移動速度が遅い場合は、アプリケーションをメモリにキャッシュすることをお勧めします。
機密データは、追加のセキュリティ制御を使用して別のパーティションに格納できます。
垂直方向のパーティション分割により、必要な同時アクセスの量を減らすことができます。
垂直パーティション分割は、データ ストア内のエンティティ レベルで動作し、エンティティを部分的に正規化して 、幅の広い 項目から 狭い 項目のセットに分割します。 HBase や Cassandra などの列指向データ ストアに最適です。 列のコレクション内のデータが変更される可能性が低い場合は、SQL Server での列ストアの使用を検討することもできます。
機能的パーティション分割
アプリケーション内の個別のビジネス領域ごとに境界付きコンテキストを識別できる場合、機能パーティション分割は、分離とデータ アクセスのパフォーマンスを向上させる方法です。 機能パーティション分割のもう 1 つの一般的な用途は、読み取り/書き込みデータと読み取り専用データを分離することです。 図 3 は、在庫データが顧客データから分離される機能パーティション分割の概要を示しています。
図 3 - 境界付きコンテキストまたはサブドメインによってデータを機能的にパーティション分割する。
このパーティション分割戦略は、システムのさまざまな部分でデータ アクセスの競合を減らすのに役立ちます。
スケーラビリティのためのパーティションの設計
最大のスケーラビリティを実現するために、各パーティションのサイズとワークロードを検討し、データが分散されるようにバランスを取る必要があります。 ただし、1 つのパーティション ストアのスケーリング制限を超えないように、データをパーティション分割する必要もあります。
スケーラビリティのためにパーティションを設計する場合は、次の手順に従います。
- アプリケーションを分析して、各クエリによって返される結果セットのサイズ、アクセスの頻度、固有の待機時間、サーバー側のコンピューティング処理要件など、データ アクセス パターンを理解します。 多くの場合、いくつかの主要なエンティティは、ほとんどの処理リソースを必要とします。
- この分析を使用して、データ サイズやワークロードなど、現在および将来のスケーラビリティ ターゲットを決定します。 次に、スケーラビリティ ターゲットを満たすために、パーティション間でデータを分散します。 水平方向のパーティション分割では、ディストリビューションが均等になるように、適切なシャード キーを選択することが重要です。 詳細については、 シャーディング パターンを参照してください。
- データ サイズとスループットの観点から、各パーティションにスケーラビリティ要件を処理するための十分なリソースがあることを確認します。 データ ストアによっては、パーティションあたりのストレージ領域、処理能力、またはネットワーク帯域幅の量に制限がある場合があります。 要件がこれらの制限を超える可能性がある場合は、パーティション分割戦略を調整するか、データをさらに分割して、2 つ以上の戦略を組み合わせる必要がある場合があります。
- システムを監視して、データが想定どおりに分散されていること、およびパーティションが負荷を処理できることを確認します。 実際の使用状況は、分析の予測と必ずしも一致するとは限りません。 その場合は、パーティションを再調整することも、必要なバランスを取るためにシステムの一部を再設計することもできます。
一部のクラウド環境では、インフラストラクチャの境界の観点からリソースが割り当てられます。 選択した境界の制限によって、データ ストレージ、処理能力、帯域幅の観点から、データ量が予想される増加に十分な余裕があることを確認します。
たとえば、Azure Table Storage を使用する場合、特定の期間に 1 つのパーティションで処理できる要求の量に制限があります。 (詳細については、 Azure Storage のスケーラビリティとパフォーマンスのターゲットに関するページを参照してください)。ビジー状態のシャードでは、1 つのパーティションで処理できるリソースよりも多くのリソースが必要になる場合があります。 その場合は、負荷を分散するためにシャードを再パーティション分割する必要がある場合があります。 これらのテーブルの合計サイズまたはスループットがストレージ アカウントの容量を超える場合は、追加のストレージ アカウントを作成し、これらのアカウントにテーブルを分散することが必要になる場合があります。
クエリ パフォーマンスのためのパーティションの設計
クエリのパフォーマンスは、多くの場合、小さいデータ セットを使用し、並列クエリを実行することで向上させることができます。 各パーティションには、データ セット全体のごく一部を含める必要があります。 この量の減少により、クエリのパフォーマンスが向上する可能性があります。 ただし、パーティション分割は、データベースを適切に設計および構成するための代替手段ではありません。 たとえば、必要なインデックスが設定されていることを確認します。
クエリ パフォーマンス用のパーティションを設計する場合は、次の手順に従います。
アプリケーションの要件とパフォーマンスを確認します。
- ビジネス要件を使用して、常に迅速に実行する必要がある重要なクエリを決定します。
- システムを監視して、実行速度が遅いクエリを特定します。
- 最も頻繁に実行されるクエリを見つけます。 1 つのクエリに最小限のコストがある場合でも、累積リソース消費量が大きくなる可能性があります。
パフォーマンスの低下の原因となっているデータをパーティション分割します。
- クエリの応答時間がターゲット内になるように、各パーティションのサイズを制限します。
- 水平パーティション分割を使用する場合は、アプリケーションが適切なパーティションを簡単に選択できるようにシャード キーを設計します。 これにより、クエリですべてのパーティションをスキャンする必要がなくなります。
- パーティションの場所を考えてみましょう。 可能であれば、アクセスするアプリケーションとユーザーに地理的に近いパーティションにデータを保持するようにしてください。
エンティティにスループットとクエリのパフォーマンス要件がある場合は、そのエンティティに基づいて機能パーティション分割を使用します。 それでも要件を満たさない場合は、水平パーティション分割も適用します。 ほとんどの場合、1 つのパーティション分割戦略で十分ですが、場合によっては両方の戦略を組み合わせる方が効率的です。
パフォーマンスを向上させるために、パーティション間でクエリを並列で実行することを検討してください。
可用性のためのパーティションの設計
データをパーティション分割すると、データセット全体が単一障害点を構成せず、データセットの個々のサブセットを個別に管理できるようにすることで、アプリケーションの可用性を向上させることができます。
可用性に影響を与える次の要因を考慮してください。
ビジネス運用にとってデータがどれほど重要であるか。 トランザクションなどの重要なビジネス情報であるデータと、ログ ファイルなどの重要度の低い運用データを特定します。
適切なバックアップ 計画を使用して、高可用性パーティションに重要なデータを格納することを検討してください。
さまざまなデータセットに対して個別の管理手順と監視手順を確立します。
同じパーティションに同じレベルの重要度を持つデータを配置して、適切な頻度で一緒にバックアップできるようにします。 たとえば、トランザクション データを保持するパーティションは、ログ情報やトレース情報を保持するパーティションよりも頻繁にバックアップする必要がある場合があります。
個々のパーティションを管理する方法。 独立した管理とメンテナンスをサポートするパーティションの設計には、いくつかの利点があります。 例えば次が挙げられます。
パーティションが失敗した場合は、他のパーティションのデータにアクセスするアプリケーションを使用せずに、パーティションを個別に復旧できます。
地理的な領域でデータをパーティション分割すると、スケジュールされたメンテナンス タスクを各場所のピーク時以外に実行できます。 パーティションが大きすぎないようにして、この期間中に計画メンテナンスが完了しないようにします。
パーティション間で重要なデータをレプリケートするかどうか。 この戦略により、可用性とパフォーマンスが向上しますが、整合性の問題が発生する可能性もあります。 変更をすべてのレプリカと同期するには時間がかかります。 この期間中、パーティションごとに異なるデータ値が含まれます。
アプリケーションの設計に関する考慮事項
パーティション分割により、システムの設計と開発が複雑になります。 システムに最初に 1 つのパーティションのみが含まれている場合でも、パーティション分割はシステム設計の基本的な部分として検討してください。 パーティション分割に後から対処する場合は、維持するライブ システムが既に存在するため、より困難になります。
- データ アクセス ロジックを変更する必要があります。
- パーティション間で分散するために、大量の既存のデータを移行する必要がある場合があります。
- ユーザーは、移行中もシステムを引き続き使用できることを期待しています。
場合によっては、初期データセットが小さく、単一のサーバーで簡単に処理できるため、パーティション分割は重要とは見なされません。 これは一部のワークロードに当てはまるかもしれませんが、多くの商用システムでは、ユーザーの数が増えるにつれて拡張する必要があります。
さらに、パーティション分割のメリットを得られるのは、大規模なデータ ストアだけではありません。 たとえば、小規模なデータ ストアは、数百の同時実行クライアントによって頻繁にアクセスされる可能性があります。 この状況でデータをパーティション分割すると、競合を減らし、スループットを向上させることができます。
データパーティション分割スキームを設計するときは、次の点を考慮してください。
パーティション間のデータ アクセス操作を最小限に抑えます。 可能であれば、最も一般的なデータベース操作のデータを各パーティションにまとめ、パーティション間のデータ アクセス操作を最小限に抑えます。 パーティション間のクエリは、1 つのパーティション内でクエリを実行するよりも時間がかかる場合がありますが、1 つのクエリ セットに対してパーティションを最適化すると、他のクエリ セットに悪影響を及ぼす可能性があります。 パーティション間でクエリを実行する必要がある場合は、並列クエリを実行し、アプリケーション内で結果を集計することで、クエリ時間を最小限に抑えます。 (この方法は、あるクエリの結果が次のクエリで使用される場合など、一部のケースでは不可能な場合があります)。
静的参照データのレプリケートを検討してください。 郵便番号テーブルや製品リストなどの比較的静的な参照データをクエリで使用する場合は、すべてのパーティションでこのデータをレプリケートして、異なるパーティションでの個別の参照操作を減らすことを検討してください。 この方法では、システム全体から大量のトラフィックが発生して、参照データが "ホット" データセットになる可能性を減らすこともできます。 ただし、参照データへの変更の同期に関連する追加コストが発生します。
パーティション間の結合を最小限に抑えます。 可能であれば、垂直パーティションと機能パーティション全体の参照整合性の要件を最小限に抑えます。 これらのスキームでは、アプリケーションはパーティション間で参照整合性を維持する役割を担います。 アプリケーションでは通常、キーと外部キーに基づいて連続するクエリを実行する必要があるため、複数のパーティション間でデータを結合するクエリは非効率的です。 代わりに、関連するデータのレプリケートまたは正規化解除を検討してください。 パーティション間結合が必要な場合は、パーティションに対して並列クエリを実行し、アプリケーション内でデータを結合します。
最終的な整合性を採用します。 厳密な整合性が実際に要件であるかどうかを評価します。 分散システムの一般的なアプローチは、最終的な整合性を実装することです。 各パーティションのデータは個別に更新され、アプリケーション ロジックによって更新がすべて正常に完了します。 また、最終的に一貫性のある操作が実行されている間に、データのクエリによって発生する可能性のある不整合も処理します。
クエリが正しいパーティションを見つける方法を検討します。 クエリですべてのパーティションをスキャンして必要なデータを見つける必要がある場合、複数の並列クエリが実行されている場合でも、パフォーマンスに大きな影響があります。 垂直パーティション分割と機能パーティション分割では、クエリでパーティションを自然に指定できます。 一方、水平方向のパーティション分割では、すべてのシャードに同じスキーマがあるため、項目の検索が困難になる可能性があります。 特定の項目のシャードの場所を検索するために使用されるマップを維持するための一般的なソリューション。 このマップは、アプリケーションのシャーディング ロジックで実装することも、透過的なシャーディングをサポートしている場合はデータ ストアによって管理することもできます。
シャードを定期的に再調整することを検討してください。 水平方向のパーティション分割を使用すると、シャードの再調整によって、サイズとワークロードによってデータを均等に分散し、ホットスポットを最小限に抑え、クエリのパフォーマンスを最大化し、物理ストレージの制限を回避できます。 ただし、これは多くの場合、カスタム ツールまたはプロセスの使用を必要とする複雑なタスクです。
パーティションをレプリケートします。 各パーティションをレプリケートすると、障害に対する保護が強化されます。 1 つのレプリカが失敗した場合は、クエリを作業コピーに向けることができます。
パーティション分割戦略の物理的な制限に達した場合は、スケーラビリティを別のレベルに拡張することが必要になる場合があります。 たとえば、パーティション分割がデータベース レベルの場合は、複数のデータベースでパーティションを検索またはレプリケートすることが必要になる場合があります。 パーティション分割が既にデータベース レベルであり、物理的な制限が問題である場合は、複数のホスティング アカウントでパーティションを検索またはレプリケートする必要がある可能性があります。
複数のパーティション内のデータにアクセスするトランザクションは避けてください。 一部のデータ ストアでは、データを変更する操作のトランザクション整合性と整合性が実装されますが、データが 1 つのパーティションに配置されている場合にのみ実装されます。 複数のパーティション間でトランザクションサポートが必要な場合は、ほとんどのパーティション分割システムでネイティブサポートが提供されないため、アプリケーション ロジックの一部としてこれを実装する必要があります。
すべてのデータ ストアには、運用管理と監視アクティビティが必要です。 タスクの範囲は、データの読み込み、データのバックアップと復元、データの再構成、システムが正しく効率的に実行されていることを確認することです。
運用管理に影響を与える次の要因を考慮してください。
データがパーティション分割されたときに適切な管理タスクと運用タスクを実装する方法。 これらのタスクには、バックアップと復元、データのアーカイブ、システムの監視、その他の管理タスクが含まれる場合があります。 たとえば、バックアップ操作と復元操作中に論理的な整合性を維持することは困難な場合があります。
データを複数のパーティションに読み込み、他のソースから到着する新しいデータを追加する方法。 一部のツールやユーティリティでは、適切なパーティションへのデータの読み込みなど、シャード化されたデータ操作がサポートされない場合があります。
定期的にデータをアーカイブおよび削除する方法。 パーティションの過剰な増加を防ぐには、定期的に (毎月など) データをアーカイブして削除する必要があります。 別のアーカイブ スキーマに一致するようにデータを変換することが必要な場合があります。
データ整合性の問題を特定する方法。 データ整合性の問題 (あるパーティション内のデータなど、別のパーティションの不足している情報を参照するデータなど) を特定するには、定期的なプロセスを実行することを検討してください。 このプロセスでは、これらの問題を自動的に修正するか、手動レビュー用のレポートを生成することができます。
パーティションの再調整
システムが成熟するにつれて、パーティション分割スキームを調整する必要がある場合があります。 たとえば、個々のパーティションでトラフィックの量が不均衡になり、ホットになり、過剰な競合が発生する可能性があります。 または、一部のパーティションのデータ量を過小評価し、一部のパーティションが容量制限に近づいている可能性があります。
Azure Cosmos DB などの一部のデータ ストアでは、パーティションを自動的に再調整できます。 それ以外の場合、再調整は、次の 2 つのステージで構成される管理タスクです。
新しいパーティション分割戦略を決定します。
- 分割する必要があるパーティション (または場合によっては組み合わせる)
- 新しいパーティション キーとは
古いパーティション分割スキームから新しいパーティション セットにデータを移行します。
データ ストアによっては、使用中のパーティション間でデータを移行できる場合があります。 これは オンライン移行と呼ばれます。 それが不可能な場合は、データの再配置中にパーティションを使用できないようにすることが必要になる場合があります (オフライン移行)。
オフライン移行
オフライン移行は通常、競合が発生する可能性が低くなるため、より簡単です。 概念的には、オフライン移行は次のように機能します。
- パーティションをオフラインに設定します。
- 分割マージし、新しいパーティションにデータを移動します。
- データを検証します。
- 新しいパーティションをオンラインにします。
- 古いパーティションを削除します。
必要に応じて、手順 1 でパーティションを読み取り専用としてマークして、アプリケーションが移動中もデータを読み取ることができるようにすることができます。
オンライン移行
オンライン移行は実行が複雑ですが、中断は少なくなります。 プロセスはオフライン移行に似ていますが、元のパーティションがオフラインとしてマークされていない点が異なります。 移行プロセスの細分性 (項目別の項目とシャード別のシャードなど) によっては、クライアント アプリケーションのデータ アクセス コードで、元のパーティションと新しいパーティションの 2 つの場所に保持されているデータの読み取りと書き込みを処理する必要がある場合があります。
次のステップ
- 特定の Azure サービスのパーティション分割戦略について説明します。 詳細については、「 データのパーティション分割戦略」を参照してください。
- Azure Storage のスケーラビリティとパフォーマンスのターゲット
関連リソース
次の設計パターンは、シナリオに関連している可能性があります。
シャーディング パターンでは、データをシャーディングするための一般的な戦略について説明します。
インデックス テーブル パターンは、データに対してセカンダリ インデックスを作成する方法を示しています。 アプリケーションは、コレクションの主キーを参照しないクエリを使用して、この方法でデータをすばやく取得できます。
具体化されたビュー パターンでは、データを集計して高速なクエリ操作をサポートする事前設定されたビューを生成する方法について説明します。 この方法は、集計対象のデータを含むパーティションが複数のサイトに分散されている場合に、パーティション分割されたデータ ストアで役立ちます。