MongoDB シャーディングの概要
スケーリング(scaling)
シャーディングについて話す前に、まずスケーリングについて見てみよう。
一般的なスケーリングで言えば、システム規模が大きくなるとスケーリング、つまり拡張が必要になる。スケーリング方法は大きく「垂直スケーリング」と「水平スケーリング」の2種類に分けられる。
垂直スケーリング
垂直スケーリングは、CPU、RAM、ストレージをより高性能なものへ交換していく方法である。スケーリングは簡単だが、そもそも CPU やメモリには限界があるため、ある程度の性能限界がある。
水平スケーリング
データセットごとにシステムを分割し、複数のサーバーから並列で処理する方法である。総合的な性能は垂直スケーリングより高くできるが、スケーリングするほど複雑性が増すため管理が難しくなる。
シャーディング(sharding)とは?
シャーディングとは、データを複数サーバーに分散させる「水平スケーリング」の仕組みである。
シャーディングには大きく3つの利点がある。「読み書き処理が速くなり、性能を上げやすい」、「ストレージを増設しやすい」、「可用性が高い」である。それぞれの詳細を以下で見ていく。MongoDB は標準機能としてシャーディング、つまり水平スケーリングをサポートする。
読み書き
データをシャードクラスターに分散して保存すると、読み書き処理、つまりファイル I/O を分散処理できる。ファイルの読み書きは遅い処理であるため、これを分散することでより高速な読み書きが可能になる。また、読み書きの負荷が増えても、サーバーを増やすことで水平スケーリングできる。
ストレージ
シャードクラスターには、分割されたデータが分散して保存される。データ量が増える場合でも、サーバーを増やして水平スケーリングできる。
高可用性
シャードクラスターでは部分的な読み書きが可能である。読み書きできない場合でも、作業を実行できるシャードサーバーから取得できることがある。
シャードクラスター
MongoDB のシャーディングは、シャード、ルーター、構成サーバーという3つの構成要素から成る。それぞれの関係と説明は次のとおりである。
シャード
シャードサーバーには、コレクションを分割した断片データ、つまりチャンクを保存する。シャードサーバーはレプリカセットとして構成できる。
ルーター
mongos はクエリルーターであり、アプリケーションからシャードクラスターへのインターフェースを提供する。シャードクラスターにアクセスするときは常に mongos 経由でアクセスする。シャード化されていないコレクションであっても、必ず mongos 経由でアクセスする。
構成サーバー
シャードクラスター設定に関するメタデータを保存する。どのシャードサーバーにデータがあるかといった情報もこのサーバーに保存される。MongoDB 3.4 以降では、構成サーバーをレプリカセットとして構成する。
シャードキー
「シャードキー」とは、データを分散してシャードサーバーに保存するときにキーとして利用する情報を指す。MongoDB は「シャードキー」を使って、コレクション内のドキュメント分散を行う。
次の図は、x シャードキーで分散された簡単な例である。
… 図 …
「シャードキー」に関するポイントは次の3つである。
- すべてのドキュメントに存在する不変のフィールド、またはフィールド群で構成する。
- 一度シャードキーを決定して分散を実行すると、シャードキーを再度変更することはできない。
- シャーディングするコレクションには、シャードキーを含むインデックスが必要である。
もちろん、シャードキーの選択が性能、効率、拡張性に大きな影響を与えることは言うまでもない。シャードキーの選択が不適切であれば、上で説明したようにシャードサーバーに偏りが発生し、非効率な動作が発生する可能性がある。
チャンク
前述のように、MongoDB は「シャードキー」の値でデータ保存を分散するが、このとき「チャンク」という塊ごとにグループ化してシャードサーバーへ分散保存する。MongoDB は自動的に「チャンク」がシャードクラスター内で均等に分散されるよう移動する。
チャンクに分割し、それを各シャードへ分散保存するイメージは以下のとおりである。
… 図 …
シャードデータに対する操作制約
シャーディングされたデータ、つまりシャードデータに対する操作にはいくつかの制限がある。
groupコマンドは使用できない。- 代わりに aggregate なしで MapReduce を利用する。
updateOneまたはdeleteOneでは_idを指定する必要がある。- シャードキー
_idが含まれていない場合はエラーが発生する。 - シャーディングしたコレクションにはユニークインデックスが必要である。
シャードコレクションと非シャードコレクション
MongoDB では、シャード化するコレクションとシャード化しないコレクションを混在させることができる。シャード化するコレクションはシャードクラスターに分散保存されるが、シャード化されていないコレクションはプライマリシャードに保存される。
データ分散方法
シャード化するときの分散方法には、「ハッシュシャード」と「レンジシャード」の2つがある。
ハッシュシャード
シャードキーのハッシュ値を利用してデータ分散を行う。ハッシュを利用したシャードの場合、シャードキーの値が近くてもチャンクが散らばりやすい特徴がある。つまり、シャードキーが単調変化する場合に分散しやすい分散方法である。逆にデータが分散されやすいため、データ構造や取得方法によってはブロードキャスト操作が増える可能性もある。
レンジシャード
シャードキーの範囲に従ってデータ分散を行う。ハッシュシャードと異なり、シャードキーの値が近い場合、同じチャンク上に存在する可能性が高くなる分散方法である。シャードキーの選定が不適切であれば、せっかくシャードという分散技術を利用しようとしても、特定サーバーに負荷が偏ってしまう可能性がある。