Docs Menu
Docs Home
/
MongoDBマニュアル
/

レプリカセットのトラブルシューティング

項目一覧

  • レプリカセットのステータス確認
  • レプリケーションラグの確認
  • Oplog エントリの低速適用
  • 全ノード間の接続テスト
  • 複数のセカンダリを再起動するときのソケット例外
  • oplog のサイズ確認

このセクションでは、 レプリカセットのデプロイをトラブルシューティングするための一般的な方法について説明します。

レプリカ セットの現在の状態と各メンバーの現在の状態を表示するには、レプリカセットのrs.status() mongoshプライマリ に接続されている セッションで メソッドを実行します。rs.status()によって表示される情報の説明については、「 replSetGetStatus 」を参照してください。

注意

rs.status() メソッドは、replSetGetStatus データベース コマンドのラッパーです。

レプリケーションラグとは、プライマリでの操作から、その操作が oplog からセカンダリに適用されるまでの遅延時間のことです。レプリケーションラグは重大な問題となり、MongoDB レプリカセットのデプロイに深刻な影響を与える可能性があります。また、レプリケーションラグが長くなりすぎると、「遅延した」ノードはすぐにプライマリになる資格を失い、分散された読み取り操作が一貫性を失う可能性が高まります。

現状のレプリケーションラグの長さを確認するには

  • プライマリに接続されている mongosh セッションで、rs.printSecondaryReplicationInfo() メソッドを呼び出します。

    各ノードの syncedTo 値を返します。これは、次の例に示すように、直近の oplog エントリがセカンダリに書き込まれた時刻を示します。

    source: m1.example.net:27017
    syncedTo: Thu Apr 10 2014 10:27:47 GMT-0400 (EDT)
    0 secs (0 hrs) behind the primary
    source: m2.example.net:27017
    syncedTo: Thu Apr 10 2014 10:27:47 GMT-0400 (EDT)
    0 secs (0 hrs) behind the primary

    プライマリの非アクティブ期間が members[n].secondaryDelaySecs の値より大きい場合、遅延ノードはプライマリより 0 秒遅れて表示されることがあります。

    注意

    rs.status()メソッドは、replSetGetStatusデータベース コマンドのラッパーです。

    MongoDB 7.0 (および6.0.13以降) 以降では、 5.0.24 )、低速クエリ ログ メッセージのtotalOplogSlotDurationMicrosは、書込み操作が storage engine の書込み (write) をコミットするためのコミット タイムスタンプを取得してから実際にコミットするまでの時間を示しています。 mongodは並列書込みをサポートします。 ただし、書込み (write) 操作はコミット タイムスタンプとともに任意の順序でコミットされます。

    次のコミット タイムスタンプを持つ書込みについて考えてみましょう。

    • 書込み A とタイムスタンプ 1

    • 書込み B とタイムスタンプ 2

    • 書込み C とタイムスタンプ 3

    書込み B が タイムスタンプ 2 で最初にコミットするとします。レプリケーションは書込み A がコミットするまで一時停止します。レプリケーションでレプリカセットのセカンダリに oplog をコピーするには、書込み A の oplog エントリとタイムスタンプ 1 が必要なためです。

  • Cloud Manager および Ops Manager で使用可能な Replication Lag グラフで、oplog 時間値がゼロ以外または増加しているかどうかを確認して、レプリケーション レートを監視します。

レプリケーションラグの主な原因

  • ネットワーク レイテンシ

    セットのメンバー間のネットワークルートに、パケットロスやネットワークルーティングの問題がないことを確認します。

    ping などのツールを使用してセットメンバー間のレイテンシをテストし、traceroute を使用してネットワーク エンドポイント間のパケットのルーティングを明らかにします。

  • ディスクのスループット

    セカンダリのファイル システムとディスク デバイスが、プライマリほど速くデータをディスクにフラッシュできない場合、セカンダリは状態を維持するのが困難になります。ディスクに関連する問題は、仮想化インスタンスなどのマルチテナント システムでは非常に一般的です。また、システムが IP ネットワーク経由でディスク デバイスにアクセスする場合(Amazon の EBS システムなど)、一時的な問題である可能性があります。

    iostatvmstat などディスクの状態を評価するには、システムレベルのツールを使用します。

  • 同時実行性

    セカンダリでのレプリケーションが、プライマリで長時間実行されている操作によってブロックされる場合があります。最良の結果を得るには、セカンダリにレプリケーションの確認を要求するように書込み保証(write concern)を設定します。これにより、レプリケーションが書込み(write)負荷に追いつかない場合に、書込み操作が完了前に結果を返さないよう防げます。

    また、データベースプロファイラーを使用して、レイテンシの発生に関連する低速クエリや長時間実行操作がないかを確認できます。

  • 適切な書込み保証(write concern)

    特に unacknowledged write concern を使用して、プライマリへの大量の書き込みを必要とする大規模なデータ取り込みまたは一括ロード操作を実行していると、セカンダリは十分な速度で oplog を読み取れず、変更に対応できなくなります。

    これを防ぐために、100、1,000、など、適切なインターバルごとに書き込み確認(書き込み保証 / write concern)をリクエストして、セカンダリがプライマリに追いつく機会を設けるようにします。

    詳しくは、以下を参照してください。

管理者は、 majority committedの遅延を設定可能な最大値flowControlTargetLagSeconds以下に抑えることを目的として、プライマリが書込み (write) を適用する速度を制限できます。

デフォルトのフロー制御は、enabled です。

注意

フロー制御を有効にするには、レプリカセットおよびシャーディングされたクラスターは、4.2FCV(featureCompatibilityVersion)を有し、かつ読み取り保証(read concern)がmajority enabled である必要があります。つまり、FCV が 4.2 でない場合や、読み取り保証(read concern)の過半数が無効になっている場合、フロー制御を有効にしても効果はありません。

フロー制御が有効になっている場合、遅延が flowControlTargetLagSeconds に近づくと、プライマリでの書き込み (write) は、書き込みを適用するためのロックを行う前にチケットを取得する必要があります。フロー制御メカニズムでは、1秒あたりに発行されるチケットの数を制限することで、遅延を目標値以下に保とうとします。

セカンダリが応答しない場合など、フロー制御を行うのに十分な負荷がレプリカセットに与えられなくても、レプリケーションラグが発生する可能性があります。

フロー制御のステータスを表示するには、プライマリで次のコマンドを実行します。

  1. rs.printSecondaryReplicationInfo() メソッドを実行して、遅延しているノードがないかどうかを確認します。

    rs.printSecondaryReplicationInfo()

    出力例:

    source: 192.0.2.2:27017
    {
    syncedTo: 'Mon Jan 31 2022 18:58:50 GMT+0000 (Coordinated Universal Time)',
    replLag: '0 secs (0 hrs) behind the primary '
    }
    ---
    source: 192.0.2.3:27017
    {
    syncedTo: 'Mon Jan 31 2022 18:58:05 GMT+0000 (Coordinated Universal Time)',
    replLag: '45 secs (0 hrs) behind the primary '
    }
  2. serverStatus コマンドを実行し、flowControl.isLagged 値を使用してレプリカセットがフロー制御を実行しているかどうかを判断します。

    db.runCommand( { serverStatus: 1 } ).flowControl.isLagged

    出力例:

    false

    フロー制御が実行されていなかった場合、セカンダリを調査して、レプリケーションラグの原因を特定します。原因としては、ハードウェア、ネットワーク、アプリケーションの制限などが挙げられます。

フロー制御に関する統計について詳しくは、以下を参照してください。

replica setのセカンダリ メンバーは、適用に低速操作しきい値よりも長い時間がかかるoplogをログに記録するようになりました。 これらの遅い oplog メッセージ:

プロファイラーは遅い oplog エントリをキャプチャしません。

レプリケーションをサポートするには、レプリカセットの全ノードが、同じレプリカセット内の他のすべてのノードに接続できる必要があります。接続が両方向であることを常に確認してください。ネットワーク トポロジーとファイアウォールの構成により、正常かつ必要な接続が妨げられ、レプリケーションがブロックされる可能性があります。

警告

インスタンスをパブリックにアクセス可能な IP アドレスにバインドする前に、クラスターを不正アクセスから保護する必要があります。 セキュリティ推奨事項の完全なリストについては、「自己管理型配置のセキュリティ チェックリスト」を参照してください。 最低限、認証を有効化し、ネットワーク インフラストラクチャの強化 を検討してください。

MongoDB バイナリ(mongodmongos)は、デフォルトで localhost にバインドされます。バイナリに net.ipv6 構成ファイルや --ipv6 コマンド ライン オプションが設定されている場合、バイナリはローカルホストの IPv6 アドレスに追加でバインドされます。

デフォルトでは、localhost にバインドされている mongodmongos は、同じコンピューター上で実行中のクライアントによる接続のみを受け入れます。このバインディング動作には、mongosh や、レプリカセットやシャーディングされたクラスターのノードなどが含まれます。リモート クライアントは、ローカルホストのみにバインドされているバイナリには接続できません。

デフォルトのバインドをオーバーライドして、他の IP アドレスにバインドするには、net.bindIp 構成ファイル設定や --bind_ip コマンド ライン オプションを使用して、ホスト名または IP アドレスのリストを指定します。

警告

たとえば、次の mongod インスタンスは、IP アドレス 198.51.100.1 に関連付けられているローカルホストとホスト名 My-Example-Associated-Hostname の両方にバインドします。

mongod --bind_ip localhost,My-Example-Associated-Hostname

このインスタンスに接続するには、リモート クライアントはホスト名またはそれに関連付けられた IP アドレス198.51.100.1を指定する必要があります。

mongosh --host My-Example-Associated-Hostname
mongosh --host 198.51.100.1

次のネットワークの双方向テストの例について考えてみましょう。

以下の 3 つの異なるノードで動作するレプリカセットがあるとします。

  • m1.example.net

  • m2.example.net

  • m3.example.net

すべてのノードで、デフォルトのポート 27017 が使用されます。

  1. m1.example.net から他のホストへの接続をテストするには、次の操作を m1.example.net で実行します。

    mongosh --host m2.example.net --port 27017
    mongosh --host m3.example.net --port 27017
  2. m2.example.net から他の 2 つのホストへの接続をテストするには、次のような操作を m2.example.net から実行します。

    mongosh --host m1.example.net --port 27017
    mongosh --host m3.example.net --port 27017

    これで、m2.example.netm1.example.net 間の接続を両方向でテストできました。

  3. m3.example.net から他の 2 つのホストへの接続をテストするには、次のような操作を m3.example.net から実行します。

    mongosh --host m1.example.net --port 27017
    mongosh --host m2.example.net --port 27017

どの方向にも接続できなかった場合、ネットワークとファイアウォールの構成を確認し、これらの接続を許可するように環境を再構成してください。

レプリカセットのノードを再起動するときは、レプリカセットがメンテナンス中にプライマリを選択できることを確認してください。これは、レプリカセットの members[n].votes の過半数が利用可能であることを保証することを意味します。

セットのアクティブ メンバーが過半数を形成できなくなると、セットのプライマリは降格してセカンダリになります。プライマリが降格しても、クライアント接続は閉じられません。

ノードによって新しいプライマリが選出されるまで、クライアントはレプリカセットに書き込みを行えません。

3 つのノードがそれぞれ 1 票を持つレプリカセットの場合、少なくとも 2 つのノードが相互接続できれば、そのセットでプライマリを選出できます。2 つのセカンダリを同時に再起動すると、プライマリが降格してセカンダリになります。少なくとも別のセカンダリが使用可能になるまで、つまり再起動したセカンダリのうち少なくとも 1 つが使用可能になるまで、そのセットにはプライマリがなく、新しいプライマリの選出もできません。

投票について詳しくは、「レプリカ セットの選挙」を参照してください。接続エラーの関連情報については、「TCP keepalive 時間が MongoDB デプロイに及ぼす影響」を参照してください。

oplog が大きいほど、レプリカセットの遅延に対する許容度が高まり、セットの回復力が高まります。

特定のレプリカセットのノードの oplog のサイズを確認するには、mongosh でそのノードに接続して rs.printReplicationInfo() メソッドを実行します。

出力には、oplog のサイズと、oplog に含まれる操作の日付範囲が表示されます。以下の例では、oplog は約 10MB で、約 26 時間(94,400 秒)の操作を格納できます。

configured oplog size: 10.10546875MB
log length start to end: 94400 (26.22hrs)
oplog first event time: Mon Mar 19 2012 13:50:38 GMT-0400 (EDT)
oplog last event time: Wed Oct 03 2012 14:59:10 GMT-0400 (EDT)
now: Wed Oct 03 2012 15:00:21 GMT-0400 (EDT)

oplogは、予想しうる最長のセカンダリのダウンタイムの間、すべてのトランザクションを保持できる長さである必要があります。[1] 少なくとも、oplog で 24 時間分の操作を保持できる必要がありますが、ユーザーの多くは、72 時間または 1 週間分の操作の保持を好みます。

oplog のサイズが操作に与える影響について詳しくは、以下を参照してください。

注意

通常、すべてのノードで oplog を同じサイズに揃えます。oplog のサイズを変更する場合は、すべてのノードでサイズを変更します。

oplogサイズを変更するには、「自己管理型レプリカセット ノードのoplogサイズの変更」チュートリアルを参照してください。

[1] oplog は、majority commit point が削除されるのを回避するために、設定されたサイズ制限を超えて大きくなることがあります。

戻る

サーバー選択アルゴリズム