MongoDB高可用複製セットの環境構築:アーキテクチャ解説と初期セットアップ手順

本番環境において単一ノード構成のMongoDBを採用することは、可用性の観点から強く推奨されません。プロセス異常やホスト障害が発生した場合、サービスは直ちに停止します。加えて、ディスク故障時にはデータ消失のリスクが伴い、代替手段が存在しません。こうしたリスクを回避し、データの冗長性と継続性を確保するために、MongoDBの複製セット(Replica Set)機能の採用が標準的です。複製セットは複数のmongodプロセスで構成され、通常1つのプライマリー(Primary)ノードと複数のセカンダリー(Secondary)ノードで構成されます。すべての書き込み処理はプライマリーノードに集中し、セカンダリーノードは_oplog_を通じてデータを複製します。

この仕組みにより、以下の核心機能が実現されます。

  • データ冗長化:書き込み発生と同時に別ノードへコピーを行い、データ消失を防ぐ。
  • 自動フェイルオーバー:プライマリーノードが応答不能になった際、レプリカセット内での投票により新しいプライマリーを自動選出する。

さらに、読み書きの分散、地理的に離れたノードへのデータレプリケーションによるディザスタリカバリ、読み取り負荷の分散といった副次的な利点も提供します。初期のMongoDBではMaster-Slave構成が採用されていましたが、マスター障害時の自動復旧ができないため、バージョン3.4以降では廃止され、現在の複製セットアーキテクチャへ移行しています。

ノード構成パターンの比較

代表的な3ノード構成には、用途に応じたバリエーションが存在します。

PSS構成(プライマリー+セカンダリー×2)

公式ガイドラインで推奨される標準的な構成です。プライマリー1ノードとセカンダリー2ノードでデータ全文を保持します。プライマリーが障害を起こした場合、残りのセカンダリーが自動で選出プロセスへ入り、新たなプライマリーへ昇格します。復旧した旧プライマリーはセカンダリーとして再参加します。データ損失のリスクが最も低い構成です。

PSA構成(プライマリー+セカンダリー+仲裁ノード)

リソースを節約したい場合や、2ノードのデータ保持で十分だが投票数が偶数になるのを避けたい場合に採用されます。仲裁(Arbiter)ノードはデータレプリカを保持せず、読み書きサービスも提供しません。純粋に選挙投票のみを担当するため、リソース消費が非常に軽微です。障害時はセカンダリーが昇格し、仲裁ノードは引き続き投票参加者として機能します。

導入時の設計要件と制約

複製セットを安定運用するためには、以下のハードウェアおよびソフトウェア上のルールを遵守する必要があります。

  • ハードウェアの同等性:全ノードはプライマリー候補となり得るため、CPU・メモリ・ディスクI/O性能を揃える必要があります。
  • 物理的/論理的な分離:同一ラックや同一ストレージコントローラーに依存すると、共通障害点(SPOF)が生じます。各ノードは独立した電源・ネットワーク・ストレージ基盤上に配置してください。
  • ソフトウェアバージョンの統一:ノード間のバージョン差異は互換性問題や予期せぬエラーを引き起こすため、全ノードで同一バージョンを使用します。
  • 書き込み性能の特性:ノード数を追加しても書き込みスループットは向上しません。複製オーバーヘッドにより、むしろ若干低下する可能性があります。

実践的な環境構築手順

検証環境やリソース制限がある場合、単一ホスト上に複数のプロセスを分散させて複製セットを構築することも可能です。ここでは、3つのノードをローカル環境で動作させるための設定例を示します。

1. ディレクトリ構造と設定ファイルの自動生成

各プロセスが競合しないよう、独立したデータディレクトリとログファイルを準備します。手動でのファイル作成を避け、バッシュスクリプトで構造と設定を生成するアプローチを採用します。

REPLICA_PORTS=(27501 27502 27503)
NODE_NAMES=("node-alpha" "node-beta" "node-gamma")
BASE_DIR="/var/lib/mongo/cluster"
REP_SET="shard-repl-01"

for i in "${!REPLICA_PORTS[@]}"; do
  PORT=${REPLICA_PORTS[$i]}
  NAME=${NODE_NAMES[$i]}
  mkdir -p "${BASE_DIR}/${NAME}/{data,logs}"
  cat > "${BASE_DIR}/${NAME}/mongod.yaml" <<EOF
storage:
  dbPath: ${BASE_DIR}/${NAME}/data
  journal:
    enabled: true
systemLog:
  destination: file
  path: ${BASE_DIR}/${NAME}/logs/mongod.log
  logAppend: true
net:
  port: ${PORT}
  bindIpAll: true
replication:
  replSetName: "${REP_SET}"
processManagement:
  fork: true
EOF
done

重要なのは、replSetNameが全ノードで完全に一致していることです。生成されたYAMLファイルには、各インスタンス固有のポート番号とストレージパスが正しく割り当てられています。

2. プロセスの起動とセキュリティ調整

設定ファイルを指定して各mongodインスタンスをバックグラウンドで起動します。

mongod --config ${BASE_DIR}/node-alpha/mongod.yaml
mongod --config ${BASE_DIR}/node-beta/mongod.yaml
mongod --config ${BASE_DIR}/node-gamma/mongod.yaml

Linux環境では、SELinuxやAppArmorが新規ポートや非標準ディレクトリへのアクセスを制限する場合があります。開発段階では、一時的にセキュリティポリシーを緩和するか、適切なコンテキスト設定を行う必要があります。

# SELinuxステータス確認
getenforce

# 一時的に緩和モードへ切り替え(検証用)
setenforce 0

各ノードが正常に起動し、指定ポート(27501〜27503)でリッスン状態になれば、物理的なインフラストラクチャの準備は完了です。続いてクライアントツールから初期化コマンドを実行し、ノード間の通信と投票ロジックを有効化します。

タグ: MongoDB replica-set database-administration high-availability data-replication

5月18日 12:38 投稿