10

昨夜、コレクションを上限付きコレクションに変換しているときに、セカンダリのオプタイムがプライマリに遅れ始めました。それはゆっくりと進み、数分ごとに数秒で、最終的にプライマリのoplogウィンドウから外れました。ここでの手順に従って、セカンダリでmongodを停止し、すべてのデータファイルを削除して再起動しましたが、プライマリを書き込みからロックするのを忘れていました。セカンダリは初期化フェーズを経て、かなりの時間がかかり、最終的にビジネスに戻りましたが、ログインしたとき、レプリケーションはさらに遅れていました。

これはクラウドなので、結局、プライマリ(すべてのデータをコピーすることになっている)のイメージを作成しましたが、書き込みが必要だったため、その時点ではdb.fsyncLock()を実行できませんでした。新しいイメージが終了し、そのイメージに基づいて新しいサーバーを起動し、レプリカセットに追加して、古いセカンダリを削除します。寿命は良好ですよね?完全ではありません-新しいセカンダリは約1時間遅れており、1日(および今夜)の間に、最終的に14時間遅れるポイントに到達します(奇妙なことに、まだoplogウィンドウ内にあります)。

「古いメンバーページの再同期」から次のステップに進みます。両方のサーバーでmongodをシャットダウンし、gzipでデータフォルダーをプライマリからセカンダリにコピーし、解凍して両方を起動します。db.fsyncLock()をプライマリにします。私の心を打つのは、同じデータを使用しても、初期化した後、私のセカンダリは1時間遅れていると言っていることです。レプリカセットに追加し直すと、5分遅れてすぐに追いつきます。

大丈夫ですよね?いいえ-フラッシュフォワード、セカンダリはゆっくりと進んでおり、現在20分遅れています。Mongostatのセカンダリは95+ロック%で固定されており、iostat -xm 2はクレイジーなものを何も表示しません。プライマリは現在書き込みを行わないためアイドル状態であり、セカンダリはまったく何もしていません(.04wMB /秒)。言及する価値があるかどうかはわかりませんが、primaryは現在、がmongoシェルなどにログインするのが遅いと感じています。

モンゴ、何ができるの?どうして追いつかないの?セカンダリーに追いつくために何が間違っているのですか?

編集 質問への回答:

  • バージョン:2.0.4
  • ハードウェア:両方のノードは同じハードウェアであり、私が知る限り、8GBのRAM、クアッドコアCPUです。仮想化されたものだと思います。
  • 書き込み速度:変動します。先に述べたように、昨夜私は上限のあるコレクションに変換していました。それがすべてを引き起こしました。一晩で、数百の小さなドキュメント(それぞれ約155バイト)を1時間に数回書き込むプロセスがあったので、最大で1時間あたり約100〜200kバイトと推定します。日中は、処理がより激しくなり、数十万の500バイトのドキュメントが更新され、さらに数十万のドキュメントが書き込まれました。まだ膨大なデータ量については話していません。EDITは、今日の初めからいくつかのiostat出力を見つけました:
デバイス:rrqm / s wrqm / sr / sw / s rkB / s wkB / s avgrq-sz avgqu-sz await r_await w_await svctm%util
xvda 1.00 2564.50 243.50 282.50 8986.00 11388.00 77.47 11.32 21.46 2.36 37.93 0.50 26.50

これは特に11wMB/ sでバースト性があり、util%は7 wMB / sで34%に達し、52 rMB / sで72%に達しました。したがって、飽和状態ではありませんが、朝の読み取りが多いワークロードであることは間違いありません。objを持っているにも関わらず面白いです。サイズが最大5GB、インデックスが最大1GB(以下を参照)の場合、ディスクアクティビティが非常に多くなります。それはすべてRAMにあるべきではありませんか?

  • ワーキングセット:ワーキングセットを計算するための受け入れられた方法論をまだ見つけていませんが、それが役立つ場合:
    「コレクション」:21
    「オブジェクト」:15540092、
    "avgObjSize":325.26198326238995、
    "dataSize":5054601144、
    "storageSize":5874327552、
    "numExtents":132、
    「インデックス」:43、
    "indexSize":864366720、
    "fileSize":10666115072、
    "nsSizeMB":16、
    「OK」:1

間違っているかもしれませんが、それが8GBのRAMを圧倒しているとは想像できません。

  • 二次からのいくつかの最近のmongostatサンプル:
insert query update delete getmoreコマンドは、マップされたvsize res障害をフラッシュします。%idx miss%qr | qw ar | aw netIn netOut conn set repl time
    * 0 * 0 * 0 * 0 0 1 | 0 0 22.2g 44.9g 912m 0 99.2 0 0 | 0 0 | 1 2k 303b 151 mySet SEC 03:47:54
    * 0 * 0 * 0 * 0 0 1 | 0 0 22.2g 44.9g 1.85g 0101 0 0 | 0 0 | 1 3k 303b 151 mySet SEC 03:48:04

編集

もっと試してみました。プライマリをシャットダウンし(現在はA、セカンダリはBになります)、データを削除し、スナップショットを解凍しました(現在、数時間前ですが、現時点では、新しいものは何も書き込んでいません)。--fastsyncを使用してAを開始しましたが、02:19:52UTC頃にハングアウトしていたB(現在はプライマリ)のオプタイムから45秒遅れています。最後に約1時間後、Aが追いついたので、Bでrs.stepDown()を呼び出します。すぐに、rs.status()は、両方のサーバーの運用時間が04:08 UTC前後であることを示していますが、B(現在はセカンダリ)は再び遅れています。 17秒までに...次に30秒...今は7分...

編集

@matulefの提案を受け取り、上限のあるコレクションでインデックスを再作成し、セカンダリのmongodプロセスを再開してから数分後、その操作時間は数秒しか増加していません。モンゴスタットからのセカンダリロック%はまだ95〜104%でホバリングしており、興味深いことに、解像度のサイズは1億から2 GBにかなり激しく変動し、1GB前後に落ち着く前に再び戻ってきました。

編集(次の夜)

ストーリーの結論-@matulefは正しい方向に進んでいたので、複製されたコレクションを上限付きコレクションに変換することにもっと注意を払う必要がありました。以下は何が起こったのかですが、私はこれをデータセーフであると宣伝していません-私はこのプロセスでいくつかのデータを失った可能性があることを自由に認めます、それでYMMV。

プライマリ(A)での上限付きコレクションのインデックスの作成はセカンダリ(B)に伝播せず、Aは(意図的にではなく)フェイルオーバーしました。Bがプライマリになると、そこでキャップされたコレクションに手動でインデックスを作成し、AをBと一致させるための再同期操作がすばやく動き始めました。残念ながら、oplogウィンドウが整列しなくなったため、BからAにデータをスナップショットする必要がありました。同じデータセットでmongoを再起動すると、AとBは再び満足し、レプリケーションが再開されました。それ以来同期します。

4

1 に答える 1

6

ここでの問題は、上限付きコレクションにはデフォルトで_idインデックスがないことです(「convertToCapped」コマンドは実際にはそのコレクションのすべてのインデックスを削除します)。セカンダリは、_idでドキュメントを参照するoplogからopsを適用して更新を実行するため、これは問題です。_idインデックスが欠落している場合、更新のたびにセカンダリで全表スキャンが必要になり、セカンダリが大幅に遅れます。

解決策は、上限付きコレクションに_idインデックスを作成することです。ただし、プライマリでインデックスを作成しても、セカンダリがすでに遅れている場合、インデックス作成操作を十分に迅速に受け取ることはできません。代わりに、問題を修正する最善の方法は、最初に各遅延セカンダリを1つずつ修正することです。それぞれについて、シャットダウンしてスタンドアロンモードで再起動し(別のポートで、-replSetオプションを使用せずに)、_ idインデックスを作成してから、セットに追加し直します。最後に、セカンダリが修正されたら、プライマリをステップダウンして、それを使用してプロセスを繰り返すことができます。

更新:mongoDB 2.0.x以前では、上限付きコレクションにはデフォルトで_idインデックスがありません。ただし、デフォルトの動作はmongoDB 2.2で変更されるようにスケジュールされているため、2.2以降で作成された上限付きコレクションでは、上限なしコレクションと同様に、_idインデックスが自動的に作成されます。2.2より前に作成された上限付きコレクションの場合でも、上記の手順を使用して_idインデックスを手動で作成する必要がありますが、新しいコレクションで上記の問題が発生することはありません。

于 2012-07-12T06:54:07.773 に答える