MongoDB: レプリカセット(高可用性)

高可用性レプリカセットの構成方法

レプリカセットは、複数のMongoDBノードが連携してデータを複数サーバー間で複製し、高可用性とパフォーマンス向上を実現する仕組みです。レプリカセットを利用することで、いずれかのノードが障害を起こしてもデータベースへのアクセスが継続でき、ワークロードを分散することでより多くのリクエストを処理できます。

3ノード構成のレプリカセット例3ノード構成のレプリカセット例

高可用性構成では、1つのノードがオフラインになっても、他のノードからデータにアクセスできます。また、すべての書き込み操作はプライマリノードに集約され、読み取り操作はセカンダリノードに分散できるため、パフォーマンスも向上します。

レプリカセットが初めての方は、MongoDB公式ドキュメントもご参照ください。

レプリカセットを構成するには、最低3台のMongoDBノードが必要です。

  1. 1台がプライマリとして、すべての書き込み操作と、デフォルトでは読み取り操作も担当します。
  2. 残りのノードはセカンダリとなり、プライマリからほぼリアルタイムでデータを継続的にレプリケーションします。

セカンダリノードが利用できなくなっても、アプリケーションは通常通り動作し続けます。セカンダリがクラスタに再参加すると、失われたデータを同期し、他のノードと同じ状態に追いつきます。

プライマリノードが障害を起こした場合、レプリカセットは自動的に新しいプライマリを選出する選挙を開始します。このプロセスは通常約10秒かかり、その間レプリカセットは読み取り専用となります。新しいプライマリが選出されると、すべての操作が通常通り再開されます。

選挙の例選挙の例

Stackheroでレプリカセットを作成するには、最低3つのMongoDBインスタンスが必要です。以下の手順で進めてください:

  1. Stackheroダッシュボードから3台(またはそれ以上)のMongoDBインスタンスを起動します。
  2. インスタンスが起動したら、ダッシュボードで各インスタンスの設定を更新します:
    1. すべてのインスタンスで同じ管理者パスワードを設定します。
    2. レプリカセットを有効化オプションを有効にします。
    3. すべてのノードで共有するレプリカ名シークレットキーを設定します。(ご注意:レプリカ名は作成後に変更できません。不明な場合は、rs-1が推奨値です。)

すべてのインスタンスで設定(管理者パスワード、レプリカセット名、レプリカシークレットキー)が完全に一致していることを必ずご確認ください。

設定を保存したら、MongoDB内でレプリカセットのメンバーを定義する必要があります。以下の手順で進めてください:

  1. Mongo CLIで接続するには、次のコマンドを使用します:
mongo --quiet mongodb://admin@<XXXXXX>.stackhero-network.com/?tls=true

Mongo CLIがインストールされていない場合は、公式Dockerイメージを次のコマンドで利用できます:

> docker run -it mongo /bin/bash

このコマンドでシェルが開き、Mongoコマンドを直接実行できます。

  1. 接続後、以下のコマンドでレプリカセットを初期化します。_idは設定したレプリカセット名に、メンバーのホスト名も適宜書き換えてください:
rs.initiate({
   _id: "rs-1",
   members: [
      { _id: 0, host: "<XXXXXX>.stackhero-network.com:27017" },
      { _id: 1, host: "<XXXXXX>.stackhero-network.com:27017" },
      { _id: 2, host: "<XXXXXX>.stackhero-network.com:27017" }
   ]
})

コマンドが成功すると、{ "ok" : 1 }のようなレスポンスが表示されます。

  1. レプリカセットの設定内容を確認したい場合は、次のコマンドを実行します:
rs.conf()

この設定は1つのノードでのみ実施すれば十分です。他のノードは自動的に更新されます。

これでMongoDBレプリカセットの構成が完了し、稼働を開始します。

レプリカセットの状態を監視できるよう、1秒ごとにステータスをチェックするNode.jsスクリプトを用意しています。このスクリプトはGitHubリポジトリで公開しています。

スクリプトのスクリーンショットスクリプトのスクリーンショット

このエラーが表示される場合、通常はTLS暗号化が有効になっていないことが原因です。接続URLにtls=trueフラグを追加することで解決できます。例:

mongodb://admin:PASSWORD@<XXXXXX>.stackhero-network.com:27017/admin?tls=true