web-dev-qa-db-ja.com

同じ作業を行うサーバーの異なるLinuxページキャッシュの動作

私は128Gメモリを備えた2セットのサーバーを持っており、それらがプロビジョニングされた時期によって区別され、まったく同じデーモン(elasticsearch)を実行している間は非常に異なる動作をします。私はログストレージではなく全文検索にelasticsearchを使用しているので、これは基本的に最小限の書き込み(1MB /秒未満)での読み取りの多い操作です。このデーモンmmapは、最大350 GBの完全なデータセットを仮想メモリに格納し、その特定の部分にアクセスして要求を処理します。これらのサーバーには、スワップスペースが構成されていません。

問題は、1セットのサーバーが正常に動作し、1秒あたり最大50の重大な障害が発生し、その需要を満たすために平均10MB /秒のディスクIOが必要になることです。パフォーマンスの低いサーバーでは、1秒あたり500の主要な障害が発生し、それを満たすには平均で最大200MB /秒のディスクIOが必要です。 disk ioの増加は、ディスクの制限である〜550MB/sに達するため、p95の応答待ち時間が短くなり、過負荷になることがあります。

それらはすべて同じロードバランサーの背後にあり、同じクラスターの一部です。 1台のサーバーの動作が悪いかどうかはわかりましたが、負荷の違いである可能性がありますが、16台のサーバーの動作が悪く、20台のサーバーが正常に動作し、異なる時間に購入+プロビジョニングされているという明確な区別があります。構成レベルが問題の原因である必要があります。

質問に答えるために、これらの動作の悪いサーバーを正常に動作するサーバーのように動作させるにはどうすればよいですか?デバッグ作業はどこに集中する必要がありますか?

以下は、3つの状態のそれぞれでsarおよび_page-types_ツールからシステムが何をしているかを調べるために収集したデータです。

ソフトウェア:-debian jessie-linux 4.9.25-elasticsearch 5.3.2-openjdk 1.8.0_141

最初に、正常に動作するサーバーからのページフォールトデータ(_sar -B_から):

_07:55:01 PM  pgpgin/s pgpgout/s   fault/s  majflt/s  pgfree/s pgscank/s pgscand/s pgsteal/s    %vmeff
08:05:01 PM   3105.89    811.60   2084.40     48.16   3385.30      0.00      0.00    810.35      0.00
08:15:01 PM   4317.65    665.28    910.29     57.03   3160.14      0.00      0.00   1047.14      0.00
08:25:01 PM   3132.84    648.48    868.41     50.00   2899.14      0.00      0.00    801.27      0.00
08:35:01 PM   2940.02   1026.47   2031.69     45.26   3418.65      0.00      0.00    764.05      0.00
08:45:01 PM   2985.72   1011.27    744.34     45.78   2796.54      0.00      0.00    817.23      0.00
08:55:01 PM   2970.14    588.34    858.08     47.65   2852.33      0.00      0.00    749.17      0.00
09:05:01 PM   3489.23   2364.78   2121.48     47.13   3945.93      0.00      0.00   1145.02      0.00
09:15:01 PM   2695.48    594.57    858.56     44.57   2616.84      0.00      0.00    624.13      0.00
_

そして、これがパフォーマンスの悪いサーバーの1つです。

_07:55:01 PM  pgpgin/s pgpgout/s   fault/s  majflt/s  pgfree/s pgscank/s pgscand/s pgsteal/s    %vmeff
08:05:01 PM 268547.64   1223.73   5266.73    503.12  71836.18      0.00      0.00  67170.50      0.00
08:15:01 PM 279865.31    944.04   3995.52    520.17  74231.90      0.00      0.00  70000.23      0.00
08:25:01 PM 265806.75    966.55   3747.43    499.45  70443.49      0.00      0.00  66407.62      0.00
08:35:01 PM 251820.93   1831.04   4689.62    475.43  67445.29      0.00      0.00  63056.35      0.00
08:45:01 PM 236055.04   1022.32   3498.37    449.37  62955.37      0.00      0.00  59042.16      0.00
08:55:01 PM 239478.40    971.98   3523.61    451.76  63856.04      0.00      0.00  59953.38      0.00
09:05:01 PM 232213.81   1058.04   4436.75    437.09  62194.61      0.00      0.00  58100.47      0.00
09:15:01 PM 216433.72    911.94   3192.28    413.23  57737.62      0.00      0.00  54126.78      0.00
_

これは、ページ再利用のLRU部分のパフォーマンスが低いことが原因であると思われます。 _while true; do echo 1 > /proc/sys/vm/drop_caches; sleep 30; done_を実行すると、マップされていないすべてのページが削除され、ディスクioの最初のスパイクが発生しますが、約30分後に落ち着きます。これをすべてのサーバーで約48時間実行して、毎日のピーク負荷と低ポイントの両方でIO)が同じように減少することを確認しました。これにより、Sarは次のように報告します。

_12:55:01 PM  pgpgin/s pgpgout/s   fault/s  majflt/s  pgfree/s pgscank/s pgscand/s pgsteal/s    %vmeff
01:05:01 PM 121327.14   1482.09   2277.40    140.25  32781.26      0.00      0.00   1764.61      0.00
01:15:01 PM 109911.39   1334.51   1057.51    130.53  31095.68      0.00      0.00   1121.39      0.00
01:25:01 PM 126500.69   1652.51   1216.76    143.07  35830.38      0.00      0.00   2801.84      0.00
01:35:01 PM 132669.45   1857.62   2309.86    148.47  36735.79      0.00      0.00   3181.19      0.00
01:45:01 PM 126872.04   1451.94   1062.94    145.68  34678.26      0.00      0.00    992.60      0.00
01:55:01 PM 121002.21   1818.32   1142.16    139.40  34168.53      0.00      0.00   1640.18      0.00
02:05:01 PM 121824.18   1260.22   2319.56    142.80  33254.67      0.00      0.00   1738.25      0.00
02:15:02 PM 120768.12   1100.87   1143.36    140.20  34195.15      0.00      0.00   1702.83      0.00
_

主要なページフォールトは、以前の値の3分の1に削減されました。ディスクから持ち込まれたページが半分になりました。これにより、ディスクIOが約200MB /秒から約100MB /秒に減少しますが、正常に動作するサーバーは、50の主要な障害/秒ですべてを大幅に上回っており、必要なのは約10MBだけです。/sのディスクIO。

LRUアルゴリズムが機能する必要があるものを確認するには、カーネルのページタイプツールを使用します。これは正常に動作するサーバーです(_page-types | awk '$3 > 1000 { print $0 }' | sort -nk3_から):

_             flags      page-count       MB  symbolic-flags                     long-symbolic-flags
0x0000000000000828          257715     1006  ___U_l_____M______________________________ uptodate,lru,mmap
0x0000000000000080          259789     1014  _______S__________________________________ slab
0x000000000000006c          279344     1091  __RU_lA___________________________________ referenced,uptodate,lru,active
0x0000000000000268          305744     1194  ___U_lA__I________________________________ uptodate,lru,active,reclaim
0x0000000000100000          524288     2048  ____________________n_____________________ nopage
0x000000000000082c          632704     2471  __RU_l_____M______________________________ referenced,uptodate,lru,mmap
0x0000000000000000          763312     2981  __________________________________________
0x0000000000000068         2108618     8236  ___U_lA___________________________________ uptodate,lru,active
0x000000000000086c         6987343    27294  __RU_lA____M______________________________ referenced,uptodate,lru,active,mmap
0x0000000000005868         8589411    33552  ___U_lA____Ma_b___________________________ uptodate,lru,active,mmap,anonymous,swapbacked
0x0000000000000868        12513737    48881  ___U_lA____M______________________________ uptodate,lru,active,mmap
             total        34078720   133120
_

これはパフォーマンスの低いサーバーです。

_             flags      page-count       MB  symbolic-flags                     long-symbolic-flags
0x0000000000100000          262144     1024  ____________________n_____________________ nopage
0x0000000000000828          340276     1329  ___U_l_____M______________________________ uptodate,lru,mmap
0x000000000000086c          515691     2014  __RU_lA____M______________________________ referenced,uptodate,lru,active,mmap
0x0000000000000028          687263     2684  ___U_l____________________________________ uptodate,lru
0x0000000000000000          785662     3068  __________________________________________
0x0000000000000868         7946840    31042  ___U_lA____M______________________________ uptodate,lru,active,mmap
0x0000000000005868         8588629    33549  ___U_lA____Ma_b___________________________ uptodate,lru,active,mmap,anonymous,swapbacked
0x0000000000000068        14133541    55209  ___U_lA___________________________________ uptodate,lru,active
             total        33816576   132096
_

そして、drop_cachesコマンドをループしたときの様子は次のとおりです。

_             flags      page-count       MB  symbolic-flags                     long-symbolic-flags
0x0000000000100000          262144     1024  ____________________n_____________________ nopage
0x0000000000000400          394790     1542  __________B_______________________________ buddy
0x0000000000000000          761557     2974  __________________________________________
0x0000000000000868         1451890     5671  ___U_lA____M______________________________ uptodate,lru,active,mmap
0x000000000000082c         3123142    12199  __RU_l_____M______________________________ referenced,uptodate,lru,mmap
0x0000000000000828         5278755    20620  ___U_l_____M______________________________ uptodate,lru,mmap
0x0000000000005868         8622864    33683  ___U_lA____Ma_b___________________________ uptodate,lru,active,mmap,anonymous,swapbacked
0x000000000000086c        13630124    53242  __RU_lA____M______________________________ referenced,uptodate,lru,active,mmap
             total        33816576   132096
_

試したこと:

  • / proc/sys/vm/vfs_cache_pressureを150〜10000のさまざまな値に増やします。これにより、IOまたは_page-types_によって報告されたデータに違いはありません。これはカーネルのバランスを取るため意味があります。構造とユーザーページ、そして私の問題は異なるユーザーページにあります
  • / proc/sys/vm/swappinessを増やします。これが何もすることを期待していなかったし、そうはしなかったが、チェックするのに害はなかった。
  • Mmapを無効にします(代わりに、epollに基づくJavaのnioを使用します)。これにより、サーバーのIOの使用法は、IOの使用法に関しては、正常に動作するものと同じように見えます。ここでの欠点は、システムのCPU%がどのように関連付けられているかです。多くのIOが発生しており、10MB /秒で約1.5%かかり、ディスクの最大100MB /秒の負荷が発生します。システムのCPU%は5〜10%です。32コアサーバーの場合これは、epollを処理するために完全に使用される1.5〜3 CPUです。nio(正常に動作するmmapサーバーと比較して)のレイテンシーも悪化しました。これはもっともらしい解決策ですが、実際に何が問題になっているのかを理解していないため、問題が発生します。
  • perfツールを使用して、スタックトレース、フレームグラフを調べたり、カーネルの動作の違いを探したりして、数え切れないほどの時間を費やしました。洞察が得られたとしてもほとんどありません。
  • チェックされたディスクの先読み設定は、サーバー間で同じです。パフォーマンスの低いサーバーのraid0はデフォルトで2048ブロック、パフォーマンスの高いサーバーのraid0はデフォルトで256ブロックです。パフォーマンスの低いサーバーを_blockdev --setra_で256に更新しても、IOの動作には影響しません。
  • Jvmを_numactl --interleave=all_で開始して、問題が2つのnumaノード間のバランスに関連していないことを確認します。違いはありませんでした。
  • vmtouchで検証されます。これは、基本的にmincore(2)を使用して、ファイルがキャッシュされているかどうかをカーネルに確認します。バッファリングされたメモリの99%以上が、データを格納するファイルシステムに使用されています。これは、上記の3つのケースすべてに当てはまります。
  • _fuser -m_で検証された、elasticsearchは、elasticsearchがデータを保存するファイルシステム上のファイルを使用する唯一のプロセスです。

すぐにテストするには:

  • 来週、誤動作しているサーバーの1つを再プロビジョニングする予定ですが、これが大きな影響を与えるとは楽観的ではありません。このプロビジョニング中に、RAIDアレイを更新してLVMをその前に配置します。 LVMと何も違うことは期待していませんが、変数を削除することは価値があるようです。
6
Erik B

これは、過度に攻撃的なディスク先読みになってしまいました。パフォーマンスの高いサーバーの先読みは128kBでした。パフォーマンスの低いサーバーの先読みは2mBでした。先読みが正確に異なる理由を突き止めることはできませんでしたが、最も可能性の高い原因は、新しいマシンのソフトウェアRAIDの前にLVMがあり、古いマシンがソフトウェアRAIDと直接通信していたことです。

私の質問は、私が最初に先読みをチェックし、違いに気づき、サーバーの1つでそれを更新したことを示していますが、mmapと先読みの間の相互作用はそれほど単純ではありません。具体的には、ファイルがmmapされると、Linuxカーネルは先読み設定をディスクからそのmmapされたファイルに関する構造にコピーします。先読み設定を更新しても、その構造は更新されません。このため、更新された先読みは、ファイルを開いたままにしているデーモンが再起動されるまで有効になりません。

先読みを減らし、パフォーマンスの低いサーバーでデーモンを再起動すると、ディスクの読み取りがパフォーマンスの良いサーバーとすぐに一致し、IO待機とテールの待ち時間がすぐに短縮されました。

3
Erik B