事象
Casssandra起動してから、ある一定期間経つと突然nodetoolがとても遅くなり、ring情報見るだけでも10秒ほどかかる場合も出ていました。CassandraだけでなくOS全体が不安定になり、SSH経由の操作すらも遅くなる事象が発生しました。
Nagiosで監視をしているのですが、nrpe自体や個別のコマンドが遅くなるのでTimeOutのアラートがいくつも飛んできて何度も夜中に起こされました。
CPUやメモリ、Diskもぱっと見た数字上では余裕があり、処理自体も遅くなっていない状態。Cassandraを再起動すると解消する。ただ、再起動後数日経過するとまた同じ事象が起こるという具合でした。
環境
S/W
S/W的には以下の環境です。
$ cat /etc/redhat-release CentOS release 6.4 (Final) $ uname -r 2.6.32-358.el6.x86_64 $ nodetool -hlocalhost version ReleaseVersion: 1.0.11 $ java -version java version "1.6.0_39" Java(TM) SE Runtime Environment (build 1.6.0_39-b04) Java HotSpot(TM) 64-Bit Server VM (build 20.14-b01, mixed mode)
H/W
H/W的には古いサーバでは起こらず、比較的新しいサーバでのみ事象が発生していました。
原因
色々調べた結果から書くと、メモリの回収処理(reclaim)が詰まってしまっているのが原因でした。
perf record
コマンドでkernelの処理確認すると、
# perf record -F 99 -g -a -- sleep 30 # perf report
メモリ関連の処理で不自然に時間かかっていることがわかりました、shrink_inactive_list
とかisolate_lru_pages.clone
とか。
更にsar -B
を見るとDirect Reclaimによる大量のPage Scan(pgscand
)をしているにも関わらず、ほとんどページが確保できていない(pgsteal
)のがわかりました。
pgscand
とpgsteal
から計算されたvmeff
は30%以下は少ないと言われているのですが、ここでは0.1%以下であることも少なくありません。
そして、このDirect Reclaimは同期処理なので、ページ確保できるまでプロセスに待ちが発生していると考えられます。
通常はkswapd
というkernelのデーモンがバックエンド非同期でページ回収してくれていると思っていたので(以下で言うとpgscank
)何かおかしいと感じました。
$ sar -B 14時07分01秒 pgpgin/s pgpgout/s fault/s majflt/s pgfree/s pgscank/s pgscand/s pgsteal/s %vmeff 14時08分01秒 655.63 30.83 2662.59 8.29 1522.72 0.00 638273.75 168.05 0.03 14時09分01秒 539.37 14.31 716.82 6.69 426.47 0.00 1875896.07 160.74 0.01 14時10分01秒 455.73 13.63 190.68 5.38 615.35 0.00 3670099.57 136.37 0.00 14時11分01秒 454.44 12.17 89.00 5.32 155.59 0.00 35332.69 59.10 0.17 14時12分01秒 472.06 15.51 1310.03 5.43 1033.46 0.00 1864225.67 237.58 0.01 14時13分01秒 563.48 14.52 102.78 6.71 415.28 0.00 2596664.08 50.05 0.00 14時14分02秒 589.45 12.08 120.35 6.70 214.24 0.00 105146.50 94.81 0.09 14時15分01秒 486.19 11.56 125.22 5.71 240.56 0.00 71915.65 126.72 0.18 14時16分01秒 452.47 11.56 91.90 5.26 316.78 0.00 35276.47 10.66 0.03
対策 Direct Reclaimを避ける
何故、ここまで多くのDirect Reclaimが発生しているかと思って調べていったところ、こちらの記事に当たりました。
ここに記載のあるzone_reclaim_modeが有効化されているとDirect Reclaimが実行されるようです。
調べたところ確かに、NUMAでかつzone_reclaim_mode=1
の設定がされているサーバで事象が発生しているのが確認できました。
NUMAかどうかはnumastat
やnumactl -H
とかでnode
が複数表示されるかで判断できます。nodeが複数あればNUMA構成のサーバです。
Cassandraでもzone_reclaim_modeを無効化するべきと、Datastaxのページにもしっかり書いてありました。
Linuxカーネルは、zone_reclaim_modeの有効化/無効化が一貫していないことがあります。この結果、パフォーマンスに予期しない問題が生じることがあります。
ということでzone_reclaim_modeを無効化する作業を行いました。
設定方法
zone_reclaim_modeが有効化されていることの確認
# cat /proc/sys/vm/zone_reclaim_mode 1
適当な名前でsysctl.dのファイルを作成してsysctlコマンドで反映させます。
# vi /etc/sysctl.d/numa_optimization.conf vm.zone_reclaim_mode=0 # sysctl -p /etc/sysctl.d/numa_optimization.conf
再起動無しでも反映されるはずです。
# cat /proc/sys/vm/zone_reclaim_mode 0
結果
Direct Reclaim(pgscand)が無くなって、kswapdでページ回収がされいます。vmeffも高い値を保っています。
OSが不安定になる事象も発生しなくなりました。
19時10分01秒 pgpgin/s pgpgout/s fault/s majflt/s pgfree/s pgscank/s pgscand/s pgsteal/s %vmeff 19時11分01秒 314.69 12.23 118.90 3.54 209.09 120.34 0.00 110.58 91.89 19時12分01秒 546.60 12.65 3963.30 6.36 1756.96 210.37 0.00 192.52 91.52 19時13分01秒 492.46 12.03 79.09 5.57 197.04 119.81 0.00 108.96 90.95 19時14分01秒 469.91 12.04 136.78 5.47 189.31 126.31 0.00 114.79 90.88 19時15分01秒 346.22 11.10 207.99 4.21 255.74 119.87 0.00 109.57 91.41 19時16分01秒 420.94 11.91 124.01 4.78 107.71 0.00 0.00 0.00 0.00 19時17分01秒 449.21 12.84 3962.40 5.12 1825.96 259.98 0.00 237.26 91.26 19時18分01秒 448.44 13.51 78.63 5.07 98.60 0.00 0.00 0.00 0.00 平均値: 623.25 15.07 1068.97 7.38 643.41 174.10 0.00 156.45 89.86
その他のチューニング項目
上記のメモリ回収のチューニングでOSが不安定になるという事象は解消したのですが、せっかくなのでいくつかメモリ周りのチューニングも行いました。
もう一つ気になっていたのがmin_free_kbytes
が90MB程度なのに対して、常に4GB程度未使用のメモリがあるということです。
$ cat /proc/sys/vm/min_free_kbytes 90112
メモリの断片化起きてそうということでbuddyinfo見ました。連続した空き領域が確認できます。左から4K、8K、16K....4Mという並びです。小さい空き領域が多いと断片化が進んでいます。左側の数字が大きいので結構断片化起きているように見えます。
$ cat /proc/buddyinfo Node 0, zone DMA 0 1 1 1 1 0 1 0 1 1 3 Node 0, zone DMA32 9989 4420 1167 155 10 1 3 2 2 8 245 Node 0, zone Normal 61577 51053 75974 9744 297 42 7 4 15 1 0 Node 1, zone Normal 104937 146173 47587 2124 114 17 8 5 36 1 0
対策② HugePage
まず、Cassandra(というかJVM)はHugePageに対応しているのでHugePageの設定を行いました。
設定方法はこちらを参照 https://tobert.github.io/tldr/cassandra-java-huge-pages.html
対策③ THP無効化
ついでにTHPもDirect Reclaim起こすらしいので、こちらも無効化しました。RedhatもDBでのTHPは推奨してないです。
5.2. Huge pages および transparent huge pages
ただし、THP はデータベースのワークロードには推奨されません。
設定方法はこちらの記事に纏まっていました。
Transparent HugePagesを無効化する - 人生は、お天気いろいろ
結果②・③
まず、Muninのグラフ見てみると、設定内容通りにメモリが使われずに常に空きメモリが多くのこってしまっていました(グラフ左側の円)。チューニング(16時頃)後はほとんどのメモリがキャッシュで使われていることがわかります(グラフ右側の円)
buddyinfo見てもかなりキレイになりました。
$ cat /proc/buddyinfo Node 0, zone DMA 0 1 1 1 1 0 1 0 1 1 3 Node 0, zone DMA32 365 158 79 59 48 37 6 3 3 2 10 Node 0, zone Normal 3612 639 778 349 86 25 8 2 2 1 0 Node 1, zone Normal 4051 847 423 263 209 59 22 3 0 1 0
参考にした情報
カーネルソースコード
https://www.kernel.org/pub/linux/kernel/v2.6/
SlideShare
http://www.slideshare.net/siburu/page-reclaim Transparent Hugepages in RHEL 6
WEB Page
https://www.kernel.org/doc/Documentation/sysctl/vm.txt
https://www.kernel.org/doc/Documentation/vm/transhuge.txt
書籍
これ一冊で完全理解 Linuxカーネル超入門(日経BP Next ICT選書)
- 作者: 日経Linux
- 出版社/メーカー: 日経BP社
- 発売日: 2014/10/16
- メディア: Kindle版
- この商品を含むブログを見る