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つがある。

ハッシュシャード

シャードキーのハッシュ値を利用してデータ分散を行う。ハッシュを利用したシャードの場合、シャードキーの値が近くてもチャンクが散らばりやすい特徴がある。つまり、シャードキーが単調変化する場合に分散しやすい分散方法である。逆にデータが分散されやすいため、データ構造や取得方法によってはブロードキャスト操作が増える可能性もある。

レンジシャード

シャードキーの範囲に従ってデータ分散を行う。ハッシュシャードと異なり、シャードキーの値が近い場合、同じチャンク上に存在する可能性が高くなる分散方法である。シャードキーの選定が不適切であれば、せっかくシャードという分散技術を利用しようとしても、特定サーバーに負荷が偏ってしまう可能性がある。