序章

トラフィックの増加に対応するには、大幅な成長が見られるアプリケーションやWebサイトを最終的に拡張する必要があります。 データ駆動型のアプリケーションとWebサイトの場合、データのセキュリティと整合性を保証する方法でスケーリングを行うことが重要です。 Webサイトやアプリケーションの人気がどれほど高くなるか、またはその人気がどれだけ長く続くかを予測するのは難しい場合があります。そのため、一部の組織は、データベースを動的に拡張できるデータベースアーキテクチャを選択しています。

この概念的な記事では、そのようなデータベースアーキテクチャの1つであるシャードデータベースについて説明します。 シャーディングは近年多くの注目を集めていますが、多くの人はそれが何であるか、またはデータベースをシャーディングすることが理にかなっているシナリオを明確に理解していません。 シャーディングとは何か、その主な利点と欠点のいくつか、およびいくつかの一般的なシャーディング方法についても説明します。

シャーディングとは何ですか?

シャーディングは、水平パーティショニングに関連するデータベースアーキテクチャパターンです。これは、1つのテーブルの行をパーティションと呼ばれる複数の異なるテーブルに分割する方法です。 各パーティションには同じスキーマと列がありますが、行もまったく異なります。 同様に、それぞれに保持されているデータは一意であり、他のパーティションに保持されているデータとは無関係です。

垂直分割との関係の観点から、水平分割を考えると役立つ場合があります。 垂直に分割されたテーブルでは、列全体が分離され、新しい別個のテーブルに配置されます。 1つの垂直パーティション内に保持されるデータは、他のすべてのデータから独立しており、それぞれが別個の行と列の両方を保持します。 次の図は、テーブルを水平方向と垂直方向の両方に分割する方法を示しています。

Example tables outlining horizontal and vertical partitioning.

シャーディングでは、データを論理シャードと呼ばれる2つ以上の小さなチャンクに分割します。 次に、論理シャードは、物理シャードと呼ばれる個別のデータベースノードに分散され、複数の論理シャードを保持できます。 それにもかかわらず、すべてのシャード内に保持されているデータは、論理データセット全体をまとめて表します。

データベースシャードは、シェアードナッシングアーキテクチャの例です。 これは、シャードが自律的であることを意味します。 同じデータやコンピューティングリソースを共有することはありません。 ただし、場合によっては、特定のテーブルを各シャードに複製して参照テーブルとして機能させることが理にかなっている場合があります。 たとえば、重量測定の固定変換率に依存するアプリケーションのデータベースがあるとします。 必要なコンバージョン率データを含むテーブルを各シャードに複製することで、クエリに必要なすべてのデータがすべてのシャードに確実に保持されるようになります。

多くの場合、シャーディングはアプリケーションレベルで実装されます。つまり、アプリケーションには、読み取りと書き込みを送信するシャードを定義するコードが含まれています。 ただし、一部のデータベース管理システムにはシャーディング機能が組み込まれているため、データベースレベルでシャーディングを直接実装できます。

シャーディングのこの一般的な概要を踏まえて、このデータベースアーキテクチャに関連するいくつかの長所と短所を見ていきましょう。

シャーディングの利点

データベースのシャーディングの主な魅力は、水平スケーリングスケールアウトとも呼ばれます)を容易にするのに役立つことです。 水平スケーリングは、負荷を分散し、より多くのトラフィックとより高速な処理を可能にするために、既存のスタックにマシンを追加する方法です。 これは、垂直スケーリング、別名スケールアップとは対照的です。これは、通常、RAMまたはCPUを追加することにより、既存のサーバーのハードウェアをアップグレードすることを含みます。

リレーショナルデータベースを単一のマシンで実行し、コンピューティングリソースをアップグレードすることで、必要に応じてスケールアップするのは比較的簡単です。 ただし、最終的には、非分散データベースはストレージと計算能力の点で制限されるため、水平方向に自由に拡張できるため、セットアップがはるかに柔軟になります。

一部の人がシャードデータベースアーキテクチャを選択するもう1つの理由は、クエリの応答時間を短縮するためです。 シャーディングされていないデータベースでクエリを送信すると、探している結果セットが見つかる前に、クエリしているテーブルのすべての行を検索しなければならない場合があります。 大規模なモノリシックデータベースを使用するアプリケーションの場合、クエリが非常に遅くなる可能性があります。 ただし、1つのテーブルを複数に分割することにより、クエリはより少ない行を処理する必要があり、その結果セットははるかに迅速に返されます。

シャーディングは、停止の影響を軽減することにより、アプリケーションの信頼性を高めるのにも役立ちます。 アプリケーションまたはWebサイトがシャーディングされていないデータベースに依存している場合、停止するとアプリケーション全体が使用できなくなる可能性があります。 ただし、シャーディングされたデータベースでは、停止が1つのシャードにのみ影響する可能性があります。 これにより、一部のユーザーがアプリケーションまたはWebサイトの一部を使用できなくなる可能性がありますが、データベース全体がクラッシュした場合よりも全体的な影響は少なくなります。

シャーディングの欠点

データベースをシャーディングすると、スケーリングが容易になり、パフォーマンスが向上しますが、特定の制限が課される場合もあります。 ここでは、これらのいくつかと、シャーディングを完全に回避する理由となる理由について説明します。

シャーディングで人々が直面する最初の問題は、シャーディングされたデータベースアーキテクチャを適切に実装することの非常に複雑なことです。 正しく行わないと、シャーディングプロセスによってデータが失われたりテーブルが破損したりする可能性があるという重大なリスクがあります。 ただし、正しく実行された場合でも、シャーディングはチームのワークフローに大きな影響を与える可能性があります。 ユーザーは、単一のエントリポイントからデータにアクセスして管理するのではなく、複数のシャードの場所にまたがってデータを管理する必要があります。これにより、一部のチームが混乱する可能性があります。

データベースをシャーディングした後にユーザーが遭遇することがある問題の1つは、シャードが最終的に不均衡になることです。 例として、2つの別々のシャードを持つデータベースがあるとします。1つは姓がAからMの文字で始まる顧客用で、もう1つは名前がNからZの文字で始まる顧客用です。 ただし、アプリケーションは、姓が文字Gで始まる膨大な数の人々にサービスを提供します。 したがって、AMシャードはNZシャードよりも多くのデータを徐々に蓄積し、ユーザーのかなりの部分でアプリケーションの速度が低下し、停止します。 AMシャードは、データベースホットスポットとして知られるものになりました。 この場合、データベースをシャーディングすることの利点は、速度低下とクラッシュによって相殺されます。 より均一なデータ分散を可能にするために、データベースを修復および再シャーディングする必要がある可能性があります。

もう1つの大きな欠点は、データベースがシャーディングされると、シャーディングされていないアーキテクチャに戻すことが非常に困難になる可能性があることです。 シャーディングされる前に作成されたデータベースのバックアップには、パーティショニング以降に書き込まれたデータは含まれません。 その結果、元のシャーディングされていないアーキテクチャを再構築するには、新しいパーティションデータを古いバックアップとマージするか、パーティションDBを単一のDBに戻す必要があり、どちらもコストと時間のかかる作業になります。

考慮すべき最後の欠点は、シャーディングがすべてのデータベースエンジンでネイティブにサポートされているわけではないことです。 たとえば、PostgreSQLには自動シャーディングが機能として含まれていませんが、PostgreSQLデータベースを手動でシャーディングすることは可能です。 自動シャーディングを含むPostgresフォークは多数ありますが、これらは多くの場合、最新のPostgreSQLリリースに遅れをとっており、他の特定の機能を欠いています。 MySQLClusterやMongoDBAtlasなどの特定のサービスとしてのデータベース製品などの一部の特殊なデータベーステクノロジには、機能として自動シャーディングが含まれていますが、これらのデータベース管理システムのバニラバージョンには含まれていません。 このため、シャーディングには「独自のロール」アプローチが必要になることがよくあります。 これは、シャーディングのドキュメントや問題のトラブルシューティングのヒントを見つけるのが難しい場合が多いことを意味します。

もちろん、これらはシャーディングの前に考慮すべきいくつかの一般的な問題にすぎません。 ユースケースによっては、データベースをシャーディングすることには、さらに多くの潜在的な欠点がある可能性があります。

シャーディングの欠点と利点のいくつかについて説明したので、シャードデータベースのいくつかの異なるアーキテクチャについて説明します。

シャーディングアーキテクチャ

データベースをシャーディングすることを決定したら、次に理解する必要があるのは、それをどのように行うかです。 クエリを実行したり、受信データをシャーディングされたテーブルやデータベースに配布したりする場合は、正しいシャードに移動することが重要です。 そうしないと、データが失われたり、クエリが非常に遅くなる可能性があります。 このセクションでは、いくつかの一般的なシャーディングアーキテクチャについて説明します。各アーキテクチャでは、わずかに異なるプロセスを使用して、シャード間でデータを分散します。

キーベースのシャーディング

キーベースのシャーディングは、ハッシュベースのシャーディングとも呼ばれ、顧客のID番号、クライアントアプリケーションのIPアドレス、郵便番号など、新しく書き込まれたデータから取得した値を使用します。等 —そしてそれをハッシュ関数に接続して、データがどのシャードに移動するかを決定します。 ハッシュ関数は、データの一部(たとえば、顧客の電子メール)を入力として受け取り、ハッシュ値と呼ばれる離散値を出力する関数です。 シャーディングの場合、ハッシュ値は、受信データが保存されるシャードを決定するために使用されるシャードIDです。 全体として、プロセスは次のようになります。

Key based sharding example diagram

エントリが正しいシャードに一貫した方法で配置されるようにするには、ハッシュ関数に入力された値がすべて同じ列からのものである必要があります。 この列は、シャードキーと呼ばれます。 簡単に言うと、シャードキーはプライマリキーに似ており、どちらも個々の行の一意の識別子を確立するために使用される列です。 大まかに言えば、シャードキーは静的である必要があります。つまり、時間の経過とともに変化する可能性のある値が含まれていてはなりません。 そうしないと、更新操作にかかる作業量が増え、パフォーマンスが低下する可能性があります。

キーベースのシャーディングはかなり一般的なシャーディングアーキテクチャですが、データベースにサーバーを動的に追加または削除しようとすると、問題が発生する可能性があります。 サーバーを追加すると、それぞれに対応するハッシュ値が必要になり、既存のエントリの多くは、すべてではないにしても、新しい正しいハッシュ値に再マップしてから、適切なサーバーに移行する必要があります。 データのリバランスを開始すると、新しいハッシュ関数も古いハッシュ関数も有効になりません。 その結果、移行中にサーバーが新しいデータを書き込むことができなくなり、アプリケーションがダウンタイムの対象となる可能性があります。

この戦略の主な魅力は、ホットスポットを防ぐためにデータを均等に分散するために使用できることです。 また、データをアルゴリズムで分散するため、範囲やディレクトリベースのシャーディングなどの他の戦略で必要となるように、すべてのデータが配置されている場所のマップを維持する必要はありません。

範囲ベースのシャーディング

範囲ベースのシャーディングには、特定の値の範囲に基づいたデータのシャーディングが含まれます。 説明のために、小売業者のカタログ内のすべての製品に関する情報を格納するデータベースがあるとします。 次のように、いくつかの異なるシャードを作成し、それらがどの価格帯に該当するかに基づいて、各製品の情報を分割することができます。

Range based sharding example diagram

範囲ベースのシャーディングの主な利点は、実装が比較的簡単なことです。 すべてのシャードは異なるデータセットを保持しますが、それらはすべて、元のデータベースと同様に、互いに同一のスキーマを持っています。 アプリケーションコードは、データが含まれる範囲を読み取り、対応するシャードに書き込みます。

一方、範囲ベースのシャーディングは、データが不均一に分散されるのを防ぎません。そのため、前述のデータベースのホットスポットが発生します。 例の図を見ると、各シャードが同じ量のデータを保持している場合でも、特定の製品が他の製品よりも注目される可能性があります。 次に、それぞれのシャードは不均衡な数の読み取りを受け取ります。

ディレクトリベースのシャーディング

ディレクトリベースのシャーディングを実装するには、シャードキーを使用してどのシャードがどのデータを保持しているかを追跡するルックアップテーブルを作成および維持する必要があります。 ルックアップテーブルは、特定のデータが見つかる場所に関する静的な情報セットを保持するテーブルです。 次の図は、ディレクトリベースのシャーディングの単純な例を示しています。

Directory based sharding example diagram

ここでは、 DeliveryZone列がシャードキーとして定義されています。 シャードキーからのデータは、それぞれの行に書き込む必要のあるシャードとともにルックアップテーブルに書き込まれます。 これは範囲ベースのシャーディングに似ていますが、シャードキーのデータがどの範囲に分類されるかを決定する代わりに、各キーは独自の特定のシャードに関連付けられます。 ディレクトリベースのシャーディングは、シャードキーのカーディナリティが低く、可能な値の数が少なく、シャードがキーの範囲を格納する意味がない場合に、範囲ベースのシャーディングよりも適切な選択です。 また、ハッシュ関数を介してシャードキーを処理しないという点で、キーベースのシャーディングとは異なることに注意してください。 キーをルックアップテーブルと照合して、データを書き込む必要がある場所を確認するだけです。

ディレクトリベースのシャーディングの主な魅力は、その柔軟性です。 範囲ベースのシャーディングアーキテクチャでは、値の範囲の指定に制限されますが、キーベースのシャーディングアーキテクチャでは、固定ハッシュ関数の使用に制限されます。これは、前述のように、後で変更するのが非常に難しい場合があります。 一方、ディレクトリベースのシャーディングでは、データエントリをシャードに割り当てるシステムやアルゴリズムを使用でき、このアプローチを使用してシャードを動的に追加するのは比較的簡単です。

ディレクトリベースのシャーディングは、ここで説明するシャーディング方法の中で最も柔軟性がありますが、すべてのクエリまたは書き込みの前にルックアップテーブルに接続する必要があると、アプリケーションのパフォーマンスに悪影響を与える可能性があります。 さらに、ルックアップテーブルは単一障害点になる可能性があります。ルックアップテーブルが破損したり、その他の方法で失敗したりすると、新しいデータを書き込んだり、既存のデータにアクセスしたりする能力に影響を与える可能性があります。

シャードする必要がありますか?

シャードデータベースアーキテクチャを実装する必要があるかどうかは、ほとんどの場合、議論の余地があります。 シャーディングを特定のサイズに達するデータベースの必然的な結果と見なす人もいれば、シャーディングによって追加される操作の複雑さのために、絶対に必要でない限り回避する必要がある頭痛と見なす人もいます。

この複雑さが増すため、シャーディングは通常、非常に大量のデータを処理する場合にのみ実行されます。 データベースをシャーディングすることが有益である可能性があるいくつかの一般的なシナリオを次に示します。

  • アプリケーションデータの量は、単一のデータベースノードのストレージ容量を超えるまで増加します。
  • データベースへの書き込みまたは読み取りの量は、単一ノードまたはその読み取りレプリカが処理できる量を超えているため、応答時間またはタイムアウトが遅くなります。
  • アプリケーションに必要なネットワーク帯域幅は、単一のデータベースノードおよび読み取りレプリカで使用可能な帯域幅を上回り、応答時間またはタイムアウトが遅くなります。

シャーディングする前に、データベースを最適化するための他のすべてのオプションを使い果たす必要があります。 検討する可能性のあるいくつかの最適化には、次のものがあります。

  • リモートデータベースのセットアップ。 すべてのコンポーネントが同じサーバー上にあるモノリシックアプリケーションで作業している場合は、データベースを独自のマシンに移動することで、データベースのパフォーマンスを向上させることができます。 データベースのテーブルはそのままであるため、これによってシャーディングほど複雑になることはありません。 ただし、それでも、インフラストラクチャの他の部分とは別に、データベースを垂直方向に拡張できます。
  • キャッシングの実装。 アプリケーションの読み取りパフォーマンスが問題の原因である場合、キャッシュはそれを改善するのに役立つ1つの戦略です。 キャッシングでは、すでに要求されているデータを一時的にメモリに保存し、後でより迅速にアクセスできるようにします。
  • 1つ以上のリードレプリカを作成しています。 読み取りパフォーマンスの向上に役立つもう1つの戦略は、1つのデータベースサーバー(プライマリサーバー)から1つ以上のセカンダリサーバーにデータをコピーすることです。 これに続いて、すべての新しい書き込みはセカンダリにコピーされる前にプライマリに送られますが、読み取りはセカンダリサーバーにのみ行われます。 このように読み取りと書き込みを分散することで、1台のマシンが過度の負荷をかけることを防ぎ、速度低下やクラッシュを防ぐことができます。 リードレプリカの作成には、より多くのコンピューティングリソースが必要であり、したがってより多くの費用がかかることに注意してください。これは、一部の人にとって重大な制約となる可能性があります。
  • より大きなサーバーへのアップグレード。 ほとんどの場合、データベースサーバーをより多くのリソースを備えたマシンにスケールアップすると、シャーディングよりも少ない労力で済みます。 リードレプリカの作成と同様に、より多くのリソースを備えたアップグレードされたサーバーは、より多くの費用がかかる可能性があります。 したがって、それが本当に最良の選択肢である場合にのみ、サイズ変更を行う必要があります。

アプリケーションまたはWebサイトが特定のポイントを超えて成長した場合、これらの戦略のいずれも、それ自体でパフォーマンスを向上させるのに十分ではないことに注意してください。 そのような場合、シャーディングは確かにあなたにとって最良の選択肢かもしれません。

結論

シャーディングは、データベースを水平方向に拡張しようとしている人にとって優れたソリューションになる可能性があります。 ただし、それはまた、非常に複雑になり、アプリケーションの潜在的な障害点を増やします。 一部の人にとってはシャーディングが必要かもしれませんが、シャーディングされたアーキテクチャを作成および維持するために必要な時間とリソースは、他の人にとってのメリットを上回る可能性があります。

この概念的な記事を読むことで、シャーディングの長所と短所をより明確に理解できるはずです。 今後は、この洞察を使用して、シャードデータベースアーキテクチャがアプリケーションに適しているかどうかについて、より多くの情報に基づいた決定を下すことができます。