Agile Cat — Azure & Hadoop — Talking Book

June 20, 2009

Database Sharding _4

Database Sharding とは、"Shared-Nothing" のアプローチである

Practicalities of Database Sharding

Database Sharding がハイ・スケーラブルで、経済的で、パフォーマンスを改善するなら、このテクノロジーは何ゆえに、もっと広範囲で採用されないのか? そして、あなたの組織において、それは実行できるのか?

Database Sharding はきわめて有用なテクノロジーなのだが、他のアプローチと同様に、実装の成功を保証するには、数多くの要因について検討しなければならないという現実がある。さらに、いくつかの限界がある。 つまり、Database Sharding は、すべてのタイプのビジネス・アプリケーションに適したものではないということだ。このチャプタでは、それらの重要な検討ポイントと、この画題に取り組んでいくための課題について説明する。

Database Sharding Challenges

それぞれのデータベースに分配される性質があるため、数多くの重要な要素について検討する必要がある:

  • Reliability : 何よりも第一に、プロダクション環境のビジネス・アプリケーションは信頼性が高く、フォールト・トレラントなはずであり、また、そして頻繁にダウンするものでは困る。 大半のケースにおいて、そのデータベース層は、あらゆる信頼性を考慮したデザインにおける、最もクリティカルで唯一の要素である。したがって、Database Sharding の実装も例外とはならない。 現実に、多数の shard データベースに分配された性質があるため、適切に設計されたアプローチが持つ重要性は、さらに大きなものとなる。 フォールト・トレラントで信頼性の高いアプローチを保証するためには、以下の各項目が必要とされる:

    • それぞれの Database Shards における、自動的なバックアップ。

    • Database Shard における冗長性、つまり、それぞれの shard における、少なくとも2つの "live" なコピーが、システム・ダウンやサーバー障害の場合に、利用できることを保証する。そこでは、ハイ・パフォーマンスで、効率的で、信頼性の高いリプリケーション・メカニズムが必要とされる。

    • それぞれのサーバーに配置され、サーバー群をまたぐ、費用効果が高いハードウェア冗長性。

    • システムダウンやサーバー障害が発生した場合の、自動的なフェイルオーバー。

    • 災害時を想定した、リカバリーのメカニズム。

  • Distributed queries 分散クエリーを用いることで、それぞれの shard サーバーで、一時的な結果が並列に処理されるため、多様なクエリーがはるかに速く処理される。このテクニックは、パフォーマンスの向上において桁違いの改善を達成し、多くのケースにおいて 10倍以上の結果を生み出す。対象となるアプリケーションへ向けて、スムーズな方式で分散クエリーを実現するためには、それぞれの shard 上にクエリーのセグメントを処理するための機能を持ち、そのアプリケーション層へ向けて、複数の結果をコンソリデートしていくことが重要となる。 分散プロセッシングから利益を得ることができる、共通のクエリーとは:

    • システム全体をまたいで、広範囲でのデータ検索を必要とする、統計値の集合体。 通常ではデータベース全体の評価を必要とする、プロダクトごとの販売量の計算などが、このようなケースの例となる。

    • 日/週/月などの範囲で、所定のプロダクトを購入した、すべての顧客リストなどの、包括的なレポートサポートするためのクエリー。

    • Avoidance of cross-shard joins内部的な結合を用いて、shard されたシステムをまたぐクエリーなどのステートメントは、きわめて非能率であり、また、実施が難しい。 正しいテクニックが適用されている限り、このような内部結合が実際のアプリケーションに必要とされることはないと、大半のケースにおいて検証されている。その主要なテクニックは、Global Tables のリプリケーションである。一般的に、この相対的に静的な参照用テーブルは、きわめて大規模なプライマリー・テーブルと結合するときに利用される。このテーブルに含まれるのは、Status Codes、Countries、Types などの値であり、Products が、このカテゴリーに分類される場合もある。 必要とされるものは、自動化されたリプリケーションのメカニズムである。それにより、Global Tables 値の、すべての shard 間での同期が保証され、クロス shard 結合へのニーズが、最小化されるか、また、完全に除去される場合もある。

        • Auto-increment key management一般的に、DBMS が提供する自動的なインクリメント機能は、シーケンシャルなキーを、データベースにインサートされる新しい Row に対して生成していく。 この考え方は、シングル・データベース・アプリケーションにとっては素晴らしいものだが、Database Sharding を使うときは、調和した形式において、すべての shard をまたぐかたちで、それらのキーを管理しなくてはならなくなる。 ここで要件は、キー生成のためのシームレスで自動化された方式を、アプリケーションに提供することである。システム全体を網羅したかたちで、キーがユニークであることを保証し、すべての shard をまたいだ運用を実現する。

            • Support for multiple Shard Schemes : Database Sharding が効果的なのは、スケーラビリティとパフォーマンスの大幅な改善という観点で、アプリケーションに対して特定されたテクノロジーを提供するためである。 その点を指摘しておくことは、重要である。 現実的に言って、その効果の度合いは、sharding アルゴリズム自身が、アプリケーションにおける問題へ向けて直接的に、どのくらいフィットしているかという点に左右される。 そこで必要とされるものは、それぞれのアプリケーション固有の問題に取り組むようにデザインされた、多数の、柔軟な、shard スキーマのセットである。 そして、特定の問題ドメインに適用されるとき、それぞれのスキーマは、本来のパフォーマンスおよび、アプリケーションに対する特性とアドバンテージを持つことになる。実際に、不適切な shard スキーマを用いると、パフォーマンスを損なう可能性が生じ、その結果が、実際に得ようとするものになってしまう。ひとつのアプリケーションに、複数の shard スキーマを用いるのも、また、一般的ではない。 アプリケーションの特定部分に適用されるスキーマが、最適な結果を達成する。 以下に、一般的な共有 shard スキーマのリストを示す:

                • Session-based sharding : 個別のユーザーやプロセスが、そのセッションの期間中に、特定の shard とインタラクトするケース。 これは、実装において最もシンプルなテクニックであり、全体的なパフォーマンスに対する実質的なオーバーヘッドもゼロになる。なぜなら、sharding を用いた判断は、セッションごとに一回しか行われないからである。 このアプローチからメリットを得るアプリケーションは、大半のケースにおいて顧客セントリックなものとなる。その理由は、前提となる顧客のすべてのデータが、ひとつの shard に含まれ、それ自体が、対象となる顧客が必要とする全てのデータになるからである。

                    • Transaction-based sharding:前提となるデータベース・トランザクションの最初の SQL Statement を調べることで、その shard について判断する。 一般的に、対象となるステートメントで用いられる "shard key" 値(Order Number など)を評価することで、その処理は完了する。続いて、そのトランザクション内の全てのステートメントを、同一の shard に方向付ける。

                        • Statement-based sharding: すべてのタイプの中で、最もプロセス集約的なものである。それぞれの SQL Statement を評価して、方向付けを行うべき適切な shard を判断する。再び、対象となる shard Key の値を評価しなければならない。 このオプションは、電話の通話記録などの、データ量が大きくトランザクションが粗いケースで用いられる。

                        • データを sharding するための、最適な方式を決定する。 このフィールドは、アプリケーションごとに変化するものであり、きわめて可変的な別の領域である。 そして、前述の Database Shard Schem での選択と、緊密に結び付けられる。 どのようにしてデータの shard を決定するかについては、数多くの方式が存在する。そして重要なことは、トランザクション・レートおよび、テーブル・ボリューム、キー・ディストリビューション、そして対象となるアプリケーションの特徴を理解することだ。 最適の sharding 戦略を決定するために、以下のデータが必要とされる:

                            • Shard by a primary key on a table: 最も簡単な選択枝であり、前提となるアプリケーションへのマップも、最も容易になる。 ただし、データの配布が適度に行われる場合のみ、効果的な手法となる。 たとえば、Customer ID (シーケンシャルな数値)による shard を選んでも、トランザクションの大半が新規の顧客のためのものとなるなら、データベースの sharding から何かが得られても、それは少しになってしまう。 その一方で、充分にして必要な分散トランザクションを実行するキーを選択すれば、きわめて大きなメリットが具体化される。

                                • Shard by the modulus of a key value:モジュール機能をキーの値に適用し、その値の計算に基づいてトランザクションを分散することで、この選択枝は数多くの状況に当てはまる。 本質的に、いかなる数の shard であっても、前もって定めることが可能となり、また、“round-robin” ベースの shard をまたいで、モジュール機能が効果的に分散されるため、新しいキー値の充分な分散をもたらすことができる。

                                    • Maintain a master shard index table :このテクニックは、特定の shard に各種の値をマップする、ひとつのマスター・テーブルの利用を伴う。 それは、きわめて柔軟であり、多種多様なアプリケーションの状況に合致する。ただし、それぞれの shard された SQL Statement のために、余計な参照が必要になるににつれて、このオプションは低いパフォーマンスを示すことになる。

                                  これまでに見てきたように、費用効果が高い方式で、新しいレベルのスケーラビリティとパフォーマンスを提供するには、Database Sharding 実装を効果的に成功させなければならない。 そのためには、数多くの考慮すべきポイントと、必要とされる機能がある。

                                  <続く>

                                  Database Sharding _1
                                  Database Sharding _2
                                  Database Sharding _3
                                  Database Sharding _4
                                  Database Sharding _5

                                   

                                  Blog at WordPress.com.