ステップバイステップガイド:基本的なMongoDBシャーディングクラスターのデプロイ
人気のNoSQLドキュメントデータベースであるMongoDBは、大量のデータを高いパフォーマンスと柔軟性で処理するのに優れています。しかし、データが増加するにつれて、単一のサーバーやレプリカセットはスケーリングの限界に達する可能性があります。ここでシャーディングが導入され、データを複数のサーバー(シャード)に分散することで水平スケーラビリティを可能にします。
この包括的なガイドでは、機能するMongoDBシャーディングクラスターを設定する全プロセスを順を追って説明します。コンフィグレーションサーバー(config servers)、mongosルーター、シャードレプリカセットといった必須コンポーネントの設定方法を学びます。このチュートリアルの終わりまでに、高い水平スケーラビリティと可用性を実現するように設計されたシャーディングクラスターをデプロイするための基礎的な理解と実践的な経験を得られるでしょう。
MongoDBシャーディングクラスターの理解
A MongoDBシャーディングクラスターは、データを分散しルーティングするために連携する3つの主要なコンポーネントで構成されています。
- シャードレプリカセット: これらが実際のデータ保持ノードです。各シャードは高可用性とデータ冗長性を提供するためにレプリカセットです。データはこれらのシャード全体にパーティション化されます。
- コンフィグレーションサーバー (Config Servers): これらは、データチャンクとシャードのマッピングを含むクラスターのメタデータを格納します。MongoDB 3.2以降、高可用性と一貫性のために、コンフィグサーバーはレプリカセット(CSRS - Config Server Replica Set)としてデプロイされる必要があります。
mongosルーター: これらはクエリールーターとして機能し、クライアントアプリケーションにインターフェースを提供します。mongosインスタンスは、クラスターのメタデータに基づいてクライアント操作を適切なシャードに誘導します。アプリケーションはシャードに直接接続するのではなく、mongosに接続します。

MongoDBシャーディングクラスターの概念図(画像提供:MongoDB公式ドキュメント)
前提条件
始める前に、以下のものが揃っていることを確認してください。
- 複数のマシン/VM: 真に分散されたシャーディングクラスターの場合、少なくとも6〜9台のマシン/VM/Dockerコンテナが必要です。この基本的なチュートリアルのために、異なるポートを使用して単一のマシン上でシミュレーションできますが、本番環境の設定では専用のリソースが必要であることを忘れないでください。
- コンフィグサーバー用: 3台(configSrv01、configSrv02、configSrv03)
- 各シャード用: 最小2〜3台(例: Shard01-RS01、Shard01-RS02、Shard01-RS03; Shard02-RS01, ...)
mongosルーター用: 1台以上
- MongoDBのインストール:
mongodまたはmongosインスタンスをホストするすべてのマシンにMongoDB 4.2+がインストールされていること。インストール手順はMongoDBドキュメントで確認できます。 - ネットワーキング: すべてのマシンが必要なポート(コンフィグサーバー、シャード、
mongosのデフォルトはそれぞれ27017、27018、27019、27020、またはカスタムポート)で相互に通信できることを確認してください。 - ディレクトリ構造: 各
mongodおよびmongosインスタンス用に専用のデータディレクトリとログディレクトリを作成します。
このガイドを簡略化するため、ここでは異なるポートとディレクトリを使用してlocalhostを使用します。本番環境では、実際のホスト名またはIPアドレスを使用します。
推奨されるディレクトリ構造(localhost設定の例)
mkdir -p /data/db/configdb01 /data/db/configdb02 /data/db/configdb03
mkdir -p /data/db/shard01-rs01 /data/db/shard01-rs02 /data/db/shard01-rs03
mkdir -p /data/db/shard02-rs01 /data/db/shard02-rs02 /data/db/shard02-rs03
mkdir -p /data/log/config /data/log/shard01 /data/log/shard02 /data/log/mongos
デプロイメント手順
ステップ 1: コンフィグレーションサーバー (Config Replica Set) の設定
コンフィグレーションサーバーは、シャーディングクラスターのメタデータを格納します。これらはレプリカセットとして実行される必要があります。
-
コンフィグサーバーの
mongodインスタンスの起動: 各インスタンスには--configsvrおよび--replSetオプションが必要です。```bash
コンフィグサーバー 1
mongod --configsvr --replSet cfgReplSet --dbpath /data/db/configdb01 --port 27019 --bind_ip localhost --logpath /data/log/config/configdb01.log --fork
コンフィグサーバー 2
mongod --configsvr --replSet cfgReplSet --dbpath /data/db/configdb02 --port 27020 --bind_ip localhost --logpath /data/log/config/configdb02.log --fork
コンフィグサーバー 3
mongod --configsvr --replSet cfgReplSet --dbpath /data/db/configdb03 --port 27021 --bind_ip localhost --logpath /data/log/config/configdb03.log --fork
```ヒント: 本番環境では、
localhostを実際のIPアドレスまたはホスト名に置き換えてください。 -
Config Replica Setの初期化: いずれかのコンフィグサーバーインスタンスに接続し、レプリカセットを初期化します。
bash mongo --port 27019mongoシェル内で:
javascript rs.initiate({ _id: "cfgReplSet", configsvr: true, members: [ { _id : 0, host : "localhost:27019" }, { _id : 1, host : "localhost:27020" }, { _id : 2, host : "localhost:27021" } ] });ステータスを確認します:
javascript rs.status();
ステップ 2: シャードレプリカセットの設定
クラスター内の各シャードはレプリカセットです。ここでは3つのメンバーを持つ2つのシャード(shard01とshard02)を設定します。
-
シャード1メンバーの
mongodインスタンスの起動: 各インスタンスには--shardsvrおよび--replSetオプションが必要です。```bash
シャード 1 メンバー 1
mongod --shardsvr --replSet shard01 --dbpath /data/db/shard01-rs01 --port 27030 --bind_ip localhost --logpath /data/log/shard01/shard01-rs01.log --fork
シャード 1 メンバー 2
mongod --shardsvr --replSet shard01 --dbpath /data/db/shard01-rs02 --port 27031 --bind_ip localhost --logpath /data/log/shard01/shard01-rs02.log --fork
シャード 1 メンバー 3
mongod --shardsvr --replSet shard01 --dbpath /data/db/shard01-rs03 --port 27032 --bind_ip localhost --logpath /data/log/shard01/shard01-rs03.log --fork
``` -
シャード 1 レプリカセットの初期化: シャード1のいずれかのインスタンスに接続します。
bash mongo --port 27030mongoシェル内で:
javascript rs.initiate({ _id : "shard01", members: [ { _id : 0, host : "localhost:27030" }, { _id : 1, host : "localhost:27031" }, { _id : 2, host : "localhost:27032" } ] }); -
シャード 2 メンバーの
mongodインスタンスの起動(追加のシャードに対して繰り返します):```bash
シャード 2 メンバー 1
mongod --shardsvr --replSet shard02 --dbpath /data/db/shard02-rs01 --port 27040 --bind_ip localhost --logpath /data/log/shard02/shard02-rs01.log --fork
シャード 2 メンバー 2
mongod --shardsvr --replSet shard02 --dbpath /data/db/shard02-rs02 --port 27041 --bind_ip localhost --logpath /data/log/shard02/shard02-rs02.log --fork
シャード 2 メンバー 3
mongod --shardsvr --replSet shard02 --dbpath /data/db/shard02-rs03 --port 27042 --bind_ip localhost --logpath /data/log/shard02/shard02-rs03.log --fork
``` -
シャード 2 レプリカセットの初期化: シャード2のいずれかのインスタンスに接続します。
bash mongo --port 27040mongoシェル内で:
javascript rs.initiate({ _id : "shard02", members: [ { _id : 0, host : "localhost:27040" }, { _id : 1, host : "localhost:27041" }, { _id : 2, host : "localhost:27042" } ] });
ステップ 3: mongosルーターの設定
mongosインスタンスは、クライアントアプリケーションのエントリーポイントです。コンフィグサーバーがどこにあるかを知っている必要があります。
-
mongosインスタンスの起動:--configdbオプションを指定し、コンフィグレプリカセットのメンバーをリストします。```bash
Mongos ルーター 1
mongos --configdb cfgReplSet/localhost:27019,localhost:27020,localhost:27021 --port 27017 --bind_ip localhost --logpath /data/log/mongos/mongos01.log --fork
```注: ロードバランシングと高可用性のために複数の
mongosインスタンスを起動できます。これらはすべて同じコンフィグサーバーに接続します。
ステップ 4: mongosへの接続とシャードの追加
次に、mongosインスタンスに接続し、シャードレプリカセットをクラスターに追加します。
-
mongosへの接続: デフォルトのMongoDBポート27017、またはmongosに指定したカスタムポートを使用します。bash mongo --port 27017 -
シャードの追加:
sh.addShard()コマンドを使用し、レプリカセット名とそのメンバーの1つを指定します。javascript sh.addShard("shard01/localhost:27030"); sh.addShard("shard02/localhost:27040");
ステップ 5: データベースとコレクションに対するシャーディングの有効化
シャードが追加されたら、特定のデータベースに対して、次にそれらのデータベース内の特定のコレクションに対してシャーディングを有効にする必要があります。これにはshard keyの選択が必要です。
-
データベースに対するシャーディングの有効化: シャーディングしたいデータベースに切り替え、
sh.enableSharding()を実行します。javascript use mydatabase; sh.enableSharding("mydatabase"); -
コレクションのシャーディング:
shard keyを選択し、sh.shardCollection()を使用します。警告: 効果的なシャードキーを選択することは、パフォーマンスと均一な分散のために非常に重要です。不適切なシャードキーは、ホットスポットや非効率的なクエリにつながる可能性があります。一般的な戦略には、ハッシュ化キー、範囲キー、または複合キーが含まれます。
この例では、フィールド
_idを持つmycollectionという名前のコレクションを想定します。```javascript
sh.shardCollection("mydatabase.mycollection"