レプリカセットのトラブルシューティング
このセクションでは、 レプリカセットのデプロイをトラブルシューティングするための一般的な方法について説明します。
レプリカセットのステータス確認
レプリカ セットの現在の状態と各メンバーの現在の状態を表示するには、レプリカセットの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 システムなど)、一時的な問題である可能性があります。
iostat
やvmstat
などディスクの状態を評価するには、システムレベルのツールを使用します。同時実行性
セカンダリでのレプリケーションが、プライマリで長時間実行されている操作によってブロックされる場合があります。最良の結果を得るには、セカンダリにレプリケーションの確認を要求するように書込み保証(write concern)を設定します。これにより、レプリケーションが書込み(write)負荷に追いつかない場合に、書込み操作が完了前に結果を返さないよう防げます。
また、データベースプロファイラーを使用して、レイテンシの発生に関連する低速クエリや長時間実行操作がないかを確認できます。
適切な書込み保証(write concern)
特に
unacknowledged write concern
を使用して、プライマリへの大量の書き込みを必要とする大規模なデータ取り込みまたは一括ロード操作を実行していると、セカンダリは十分な速度で oplog を読み取れず、変更に対応できなくなります。これを防ぐために、100、1,000、など、適切なインターバルごとに書き込み確認(書き込み保証 / write concern)をリクエストして、セカンダリがプライマリに追いつく機会を設けるようにします。
詳しくは、以下を参照してください。
フロー制御
管理者は、 majority
committed
の遅延を設定可能な最大値flowControlTargetLagSeconds
以下に抑えることを目的として、プライマリが書込み (write) を適用する速度を制限できます。
デフォルトのフロー制御は、enabled
です。
注意
フロー制御を有効にするには、レプリカセットおよびシャーディングされたクラスターは、4.2
の FCV(featureCompatibilityVersion)を有し、かつ読み取り保証(read concern)がmajority enabled
である必要があります。つまり、FCV が 4.2
でない場合や、読み取り保証(read concern)の過半数が無効になっている場合、フロー制御を有効にしても効果はありません。
フロー制御が有効になっている場合、遅延が flowControlTargetLagSeconds
に近づくと、プライマリでの書き込み (write) は、書き込みを適用するためのロックを行う前にチケットを取得する必要があります。フロー制御メカニズムでは、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 ' } serverStatus
コマンドを実行し、flowControl.isLagged
値を使用してレプリカセットがフロー制御を実行しているかどうかを判断します。db.runCommand( { serverStatus: 1 } ).flowControl.isLagged 出力例:
false フロー制御が実行されていなかった場合、セカンダリを調査して、レプリケーションラグの原因を特定します。原因としては、ハードウェア、ネットワーク、アプリケーションの制限などが挙げられます。
フロー制御に関する統計について詳しくは、以下を参照してください。
Oplog エントリの低速適用
replica setのセカンダリ メンバーは、適用に低速操作しきい値よりも長い時間がかかるoplogをログに記録するようになりました。 これらの遅い oplog メッセージ:
ログは、テキスト
applied op: <oplog entry> took <num>ms
を含むREPL
コンポーネントの下にあります。ログレベルに依存しない(システムレベルでもコンポーネントレベルでも)
プロファイル レベルに依存しないでください。
slowOpSampleRate
の影響を受けます。
プロファイラーは遅い oplog エントリをキャプチャしません。
全ノード間の接続テスト
レプリケーションをサポートするには、レプリカセットの全ノードが、同じレプリカセット内の他のすべてのノードに接続できる必要があります。接続が両方向であることを常に確認してください。ネットワーク トポロジーとファイアウォールの構成により、正常かつ必要な接続が妨げられ、レプリケーションがブロックされる可能性があります。
警告
インスタンスをパブリックにアクセス可能な IP アドレスにバインドする前に、クラスターを不正アクセスから保護する必要があります。 セキュリティ推奨事項の完全なリストについては、「自己管理型配置のセキュリティ チェックリスト」を参照してください。 最低限、認証を有効化し、ネットワーク インフラストラクチャの強化 を検討してください。
MongoDB バイナリ(mongod
と mongos
)は、デフォルトで localhost にバインドされます。バイナリに net.ipv6
構成ファイルや --ipv6
コマンド ライン オプションが設定されている場合、バイナリはローカルホストの IPv6 アドレスに追加でバインドされます。
デフォルトでは、localhost にバインドされている mongod
と mongos
は、同じコンピューター上で実行中のクライアントによる接続のみを受け入れます。このバインディング動作には、mongosh
や、レプリカセットやシャーディングされたクラスターのノードなどが含まれます。リモート クライアントは、ローカルホストのみにバインドされているバイナリには接続できません。
デフォルトのバインドをオーバーライドして、他の IP アドレスにバインドするには、net.bindIp
構成ファイル設定や --bind_ip
コマンド ライン オプションを使用して、ホスト名または IP アドレスのリストを指定します。
警告
MongDB5.0 以降、 スプリットホライズンDNS IP アドレスのみが設定されているノードは起動時の検証に失敗し、エラーを報告します。詳しくはdisableSplitHorizonIPCheck
を参照してください。
たとえば、次の 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
が使用されます。
m1.example.net
から他のホストへの接続をテストするには、次の操作をm1.example.net
で実行します。mongosh --host m2.example.net --port 27017 mongosh --host m3.example.net --port 27017 m2.example.net
から他の 2 つのホストへの接続をテストするには、次のような操作をm2.example.net
から実行します。mongosh --host m1.example.net --port 27017 mongosh --host m3.example.net --port 27017 これで、
m2.example.net
とm1.example.net
間の接続を両方向でテストできました。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 が大きいほど、レプリカセットの遅延に対する許容度が高まり、セットの回復力が高まります。
特定のレプリカセットのノードの 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 が削除されるのを回避するために、設定されたサイズ制限を超えて大きくなることがあります。 |