2017-06-06 9 views
3

私はsharded mongoクラスタ(5つのシャード)に対してクエリと更新操作を実行していますが、これははっきりと説明するのに苦労しています。これは、アプリケーションのセットアップです:予期せぬmongodbの更新がブロックされました

  • モンゴのv3.0.12
  • のJava 8(スタンドアロンJVM)

典型的なバックグラウンド負荷がプライマリー断片に、このようになります

  • Morphia v1.3.2デベロッパー(使用しますmongostat):プライマリー断片に

    insert query update delete getmore command % dirty % used flushes vsize res qr|qw ar|aw netIn netOut conn set repl  time 
        4 3120 785  *0  172 577|0  0.9 80.7  0 72.7G 40.9G 0|1 2|7 2m 163m 3420 rs0 PRI 15:46:29 
        4 2324 475  *0  129 417|0  1.3 80.9  0 72.7G 40.9G 0|0 3|2 1m 124m 3420 rs0 PRI 15:46:30 
        1 2503 425  *0  121 290|0  1.4 81.0  0 72.7G 40.9G 0|1 1|6 1m 114m 3420 rs0 PRI 15:46:31 
        4 2322 469  *0  194 371|0  1.6 81.1  0 72.7G 40.9G 0|2 1|1 1m 86m 3420 rs0 PRI 15:46:32 
        4 3349 435  *0  194 443|0  1.8 81.2  0 72.7G 40.9G 0|0 1|1 2m 83m 3420 rs0 PRI 15:46:33 
        2 3071 474  *0  159 338|0  2.2 81.6  0 72.7G 40.9G 0|0 1|0 1m 87m 3420 rs0 PRI 15:46:34 
        2 2661 394  *0  119 239|0  2.3 81.6  0 72.7G 40.9G 0|0 1|8 925k 81m 3420 rs0 PRI 15:46:35 
    

    接続:

    rs0:PRIMARY> db.serverStatus().connections 
    { 
         "current" : 3388, 
         "available" : 47812, 
         "totalCreated" : NumberLong(338643) 
    } 
    

    RS0リソース統計:シーンを設定します

    AWS System stats

    うまくいけば。

    • アプリケーションサーバーAは1つの
    • アプリケーションサーバーBはコレクション2
    への照会や更新を行い、コレクションへのクエリや更新を実行します。私は、同じDBが、異なるコレクションと対話する2つのアプリケーションサーバーを持っています

    私は最近、アプリケーションサーバーBに新しい$ set更新操作を追加しました。アプリケーションサーバーAの更新パフォーマンスを大幅に低下させる不都合な副作用があったようです(前に< 1秒かかる操作は、 60秒)。

    Iは、アプリケーションサーバAで、これはnewrelic CPUプロファイリングなどの場合であると考えて設定された動作は、アプリケーションサーバBで実行されている間、次の結果を生成している。

    Performance of update with SET operation

    同じノードセット操作は、アプリケーションサーバB上で実行しなくても、プロファイラで:

    Performance of update without SET operation

    私はこれらから注意して、新たなSET動作中に(APPLにアプリケーションサーバーB)のmongo更新操作(アプリケーションサーバーA)は、合計CPU時間の約25%を消費しています。 SET操作は実行されていませんが、同等の操作は〜5%しか消費しません。

    私が最初に想定していたのは、mongoクラスタで何らかのパフォーマンスボトルネックが発生していたということでした。私は様々な原因が考えられている:SET操作は、アプリケーションサーバB上で実行されている間、ここで

    は、RS0からmongostat出力です:

    insert query update delete getmore command % dirty % used flushes vsize res qr|qw ar|aw netIn netOut conn set repl  time 
        *0 1405  1  *0  19 132|0  0.0 80.0  0 72.1G 40.9G 0|0 1|0 153k 11m 3419 rs0 PRI 15:46:08 
        *0 1340  *0  *0  18 121|0  0.0 80.0  0 72.1G 40.9G 0|0 1|0 144k  7m 3419 rs0 PRI 15:46:09 
        *0 1677  *0  *0  27 263|0  0.0 80.1  0 72.1G 40.9G 0|0 1|0 230k  9m 3419 rs0 PRI 15:46:10 
        *0 1415  4  *0  35 198|0  0.0 80.0  0 72.1G 40.9G 0|0 1|0 183k  9m 3419 rs0 PRI 15:46:11 
        *0 1350  *0  *0  17 123|0  0.0 80.0  0 72.1G 40.9G 0|0 1|0 143k 14m 3419 rs0 PRI 15:46:12 
        *0 1036  *0  *0  21 141|0  0.0 80.0  0 72.1G 40.9G 0|0 1|0 130k  9m 3419 rs0 PRI 15:46:13 
        1 1099  *0  *0  20 139|0  0.0 80.0  0 72.1G 40.9G 0|0 2|0 132k  8m 3419 rs0 PRI 15:46:14 
    

    私は負荷での大幅な低下に注意してください。 AWSシステムのメトリックは、同様の画像を表示し、CPU負荷が&のIN/OUTのCPU負荷が低下します。

    はそれがSET操作中にノードへの接続数です:

    rs0:PRIMARY> db.serverStatus().connections 
    { 
         "current" : 3419, 
         "available" : 47781, 
         "totalCreated" : NumberLong(338788) 
    } 
    

    はい、ではなく、私はそれが問題だと考えているポイントへの接続数の増加があります。

    私はおそらくSET操作が遅いと思っていましたので、dbプロファイリングをslowMSしきい値2秒で有効にしました。 SET操作の期間中、低速クエリログは(アプリケーションサーバーAの既知の低速操作のため)単一のエントリしか取得しなかったため、そこには何も役立ちません。

    それからIOSTATを使用して、インスタンスSSDストアを使用するように構成されたジャーナルボリュームの性能に見えた:

    iostat -x 5 -t 
    

    これは、同様にmongostatと同様の画像を示し、負荷がときに減少するように見える、すなわちアプリケーションサーバーAのスローダウン/ブロッキングアップデートが表示されますが、SET操作が実行されている間はアプリケーションサーバーBで実行されています。

    残念ながら、私はアイデアとデバッグの考え方が不足しています。私はこの問題を解決する上でさらなる助けに感謝します。

  • +0

    今後の検討では、レプリケーションの遅延(MAJORITY書き込み問題を使用しています)を検討します。 – MarcF

    答えて

    0

    それは、この問題の原因だったことが表示されます:

    • レプリカが遅れ始めた場合、同じモンゴクラスタに行く他のDB操作をブロックする大多数の書き込みの懸念を使用します。
    • 遅れの原因は、$ pushを使用したことです。これは特定のシャードのためにホットスポットを作成していました。詳細はhttps://jira.mongodb.org/browse/SERVER-9784を参照してください。
    関連する問題