ウェブサイト作成は、インターネット上での存在感を確立するための最初のステップです。さらに長期的に発展していくためには、サイトの成長に合わせた拡張性を確保する必要があります。拡張性と言えば、データベースを無視する訳にはいきません。これを意識しないと、クエリのパフォーマンスが低下し、不意にデータベースが停止する危険性があります。

この記事では、データベースシャーディングを使用して、データの高いスケーラビリティと可用性を実現する方法をご紹介します。また、シャーディングの欠点と、使用できるさまざまなシャーディングアーキテクチャについても触れたいと思います。

データベースシャーディングとは

シャーディングとは、テーブルを他のデータベースサーバーに分散させる最適化手法のことです。データをより小さなサブセット(チャンク)に分割するという意味では、パーティショニングと同じです。シャーディングは、サブセットを複数サーバーに分散させるのに対し、パーティショニングは1つのデータベースに格納するという違いがあります。複数サーバーは、同じデータベースエンジンとハードウェアタイプを使用し、すべてのシャーディングで同じパフォーマンスレベルを保持します。

シャーディングは、シェア・ナッシング・アーキテクチャを実現し、処理のボトルネックや単一障害点を排除することを目的としたシステムです。

An illustration to explain database sharding.
シャーディングの一例(画像参照元:Analytics Vidhya

シャーディングは水平方向と垂直方向の2つの方法で実装することができます。水平方向のシャーディングは行(レコード)を基準にテーブルを分割し、垂直方向のシャーディングは列(カラム)を基準にテーブルを分割します。

この点で、シャーディングはパーティショニングのようなもので、大きなテーブルを小さなテーブルに分割することができます。

水平方向のシャーディングは、ほとんどのクエリが行のサブセットを返すようなデータベースで有効で、例えば、顧客データベースではデータ(名前、住所、メールアドレスなど)を一度に返すことができます。

垂直方向のシャーディングは、クエリが単一の列を返すようなデータベースで有用です。例えば、顧客データベースが顧客の名前やメールアドレスを別々に返す場合、名前とメールアドレスを別のクラスタに分離することが可能です。

データベースにおけるシャーディングの利点

データベースシャーディングの利点は以下の通りです。

水平方向のスケーリングの強化

データベースのスケーリングは、垂直方向にも水平方向にも行うことができます。垂直方向のスケーリングとは、サーバーに中央処理装置(CPU)とランダムアクセスメモリ(RAM)を追加し、パフォーマンスを引き上げることを意味します。垂直方向のスケーリングは、小規模から中規模のデータベースには有効なソリューションです。しかし、データが増大するにつれて、垂直スケーリングは実現不可能になります。1台のサーバーに追加できるパワーには限りがあります。

一方で、水平スケーリングはより柔軟です。水平スケーリングでは、システムにさらにサーバーを追加することで、必要に応じてデータベースを拡張することができます。サーバーそれぞれが、データベースシャードにリソースを提供することになります。これにより、作業負荷が分散され、システムの処理能力が向上し、より多くのリクエストに対応できるようになります。

クエリ応答時間の短縮

シャードは数行の行と列で構成されます。そのため、データベースのクエリを処理する時間は短くなります。一方、シャード化されていないデータベースクエリでは、何百、何千もの行を検索する必要があります。

障害時の信頼性向上

データベースは、誤ってデータを削除してしまったり、接続エラーやサイバーセキュリティ攻撃など、さまざまな理由で停止することがあります。シャーディングは、このような障害を最小限に抑えます。各シャードが自律的に動作するため、ダウンが発生しても影響を受けるシャードは一部にとどまります。例えば、4つのシャードがあり、そのうちの1つに障害が発生した場合であっても、実際の業務に影響が出るのは25%です。

シャーディングの欠点

シャーディングは、データベースの信頼性と可用性を向上させますが、その実装は複雑です。間違ったシャーディングアーキテクチャを使用すると、パフォーマンスが低下し、データ消失につながる可能性すらあります。

すべてのシャー ドにバランスよくデータが分散されるようなシャーディングの手法を選択する必要があります。バランスがとれていないと、データベースのホットスポットが発生する危険性があります。これはつまり、あるシャードにはほとんどのデータが格納されているのに、他のシャードにはほとんどデータがない状態です。そのような状況では、単一シャードへの書き込みスループットが低下します。

この問題を解決するには、バランスの取れていないシャードをさらに分割すればよいのですが、このプロセスは困難で、データを移行する間にデータベースが停止してしまう可能性があります。

また、シャーディングの欠点として、複数シャードにまたがるSQLのテーブル結合を行うと処理に時間がかかり、パフォーマンスが低下する可能性が挙げられます。しかし、適切なアーキテクチャを用いれば、この問題を回避することができます。

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

シャーディングは3つのアーキテクチャで実装することができます。

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

どのアーキテクチャを選ぶかは、個々の状況によって異なります。

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

キーベース、もしくはハッシュベースのシャーディングアーキテクチャでは、データベースアプリケーションはシャードキーを使ってシャードの場所を特定します。ハッシュ関数がシャーディングキーの値をハッシュ化し、その出力がデータを特定のシャードにマッピングする仕組みです。単純なハッシュ関数としては、モジュロ演算子やシャードの数があります。

ハッシュ関数は、複数のシャーディングキーを取ることができます。このため、キーベースのシャーディングは、キーを共有する可能性のあるデータレコードに適しています。アルゴリズム的にデータを分散させることで、あるシャードが他のシャードより多くのデータを含むデータベースのホットスポットを生み出す可能性を最小限に抑えることができます。

しかし、分散はハッシュ関数にのみ依存しているため、データを論理的にグループ化することはできません。そのため、複数のシャードのデータを必要とするデータベース操作では、各シャードからデータを読み込む必要があり、効率が悪くなる可能性があります。

レンジベースのシャーディング

レンジベースのシャーディングは、指定した値の範囲に応じてデータベースをシャーディングするものです。

ある値をどのシャードに割り当てるかは、シャーディングキーを使って決定します。データベースアプリケーションが、ルックアップテーブルでシャーディングキーに対応するシャードを確認し、データを格納します。このため、レンジベースのシャーディングは設計や実装が容易です。

例えば、ユーザーデータベースのユーザーIDの値をシャーディングキーとして使用することができます。0〜2,000のIDを持つユーザーをあるシャーディングに、2,000〜4,000のIDを持つユーザーを別のシャーディングに…といった具合に保存していくことができます。

レンジベースのシャーディングは、データベースのホットスポットを引き起こす可能性があります。例えば、2,001から4,000までのユーザーIDを持つユーザーデータベースを考えてみましょう。この場合、ユーザーIDは2,001から4,000の間にあることが多いのですが、これを1つのシャードに割り当てるため、時間の経過とともにバランスが崩れていきます。したがって、レンジベースのシャーディングは、データが均等に分散していることが明らかな場合に有用です。

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

ディレクトリベースのシャーディングは、論理的に関連するデータを同じシャードにグループ化することができます。これには、データベース内の各エンティティのマッピング情報一覧を含むルックアップテーブルが使用されます。各マッピングがデータベースシャードに対応します。

ディレクトリベースのシャーディングは、レンジベースやキーベースのシャーディングよりも柔軟で、動的にデータをシャー ドに追加することができます。シャードへのデータ追加は動的に行われるため、シャード関数に従う必要はなく、範囲値も必要ありません。この柔軟性により、データベースの効率が向上します。関連するデータを1つのシャードに格納できるため、一般的なクエリの実行にかかる時間が短縮可能です。

例えば、ディレクトリベースのシャーディングを使用して、ユーザーを位置情報によってグループ化し、特定の場所からユーザーを取得する場合、1つのシャードにクエリを実行するだけでOKです。

Kinstaのデータベースシャーディング

最近のデータベースエンジンのほとんどが、データベースのシャーディングをサポートしています。例えばMariaDBは、MySQLの商業的にサポートされているフォークという位置付けです。IBM、GitHub、Wikimediaなどで採用されている高パフォーマンスのオープンソースデータベースシステムです。また、Kinstaのハイパフォーマンスサーバースタックの一部でもあります。

MariaDBでは、Spiderストレージエンジンを通じて、ビルトインのシャーディング機能を利用することができます。Spiderは、パーティショニングと拡張アーキテクチャ(XA)トランザクションをサポートするクラスタ形成エンジンです。これにより、異なるインスタンスのリモートテーブルを、あたかも同じインスタンスにあるかのように扱うことができます。Spiderでテーブルを作成すると、そのテーブルはリモートMariaDBサーバー内の別のテーブルにリンクされます。接続を確立すると、ストレージエンジンにより、同じトランザクションの一部であるすべてのテーブルとリンクが共有される仕組みです。

まとめ

データベースのシャーディングは、テーブルを小さなサブセット(チャンク)に分割し、シャードと呼ばれる複数のサーバーに分散するスケーリング技術です。キーベース、レンジベース、ディレクトリベースなど、さまざまな手段でシャーディングを実装することができます。

シャーディングはデータベースのスケーラビリティ、信頼性、可用性を高めるものの、実装が非常に複雑です。さらに、一度シャーディングを作成すると、データベースをシャーディングのない状態に戻すのは容易ではありません。このため、シャーディングによる最適化は、他のスケーラビリティオプションではうまくいかないとはっきりした場合にのみ使用することをおすすめします。

非営利団体であっても、企業レベルの事業であっても、Kinstaの専門的なソリューションがお客様のサイトホスティングのお悩みを取り除き、最も重要な業務への集中をお手伝いします。

Salman Ravoof

Salman Ravoof is a self-taught web developer, writer, creator, and a huge admirer of Free and Open Source Software (FOSS). Besides tech, he's excited by science, philosophy, photography, arts, cats, and food. Learn more about him on his website, and connect with Salman on Twitter.