Hadoopのworker系nodeでのkernel panic

6月ごろからHadoopのworker系nodeつまりdatanode, nodemanager, presto workerが動いているnodeでkernel panicが多発するようになって困っていてまだ解決はしていないのですが、メモっておきます。

ログ分析基盤として使っているHadoopクラスタで深夜帯にバッチを動かします。
load averageは100を超えることもあり、マシンスペックはメモリ256GB、CPUは40プロセッサ、HDDは3TBが12本ささってます。
OSはCentOS 7.2.1511です。
データ量が増えてきたこともあり、ディスクだけじゃなくコンピューティングリソースももりもり使ってます。

だいたい午前6時から8時にkernel panic起こることが多くて、ひどいときは短い時間に3台kernel panicが起きて、マシン再起動、サービス起動が間に合わずmissing blockになってjobが失敗することもありました。
負荷がピークの時に起きているわけではないのがちょっと不思議なのですが、別の負荷がそんなに高くないHadoopクラスタでは全く起きてないので負荷が原因のひとつではありそう。

この状況はさすがに辛いので、ジョブのスケジューリングを変えて負荷を平準化するとともに、インフラチームから提案のあったkernelアップグレードをやったところ回数こそ減ったもののまだ週一回程度起きます。
さらに仮にkernel panicしても、マシン再起動したらdatanode, nodemanager, presto workerが自動起動するようにsystemctlにType=oneshotで仕込みました。

ただ

Wants=network-online.target
After=network-online.target

とかやっても期待通りに動かなかったので、

After=network.target remote-fs.target nss-lookup.target ambari-agent.service

とかしてさらにsleep 45してマシン再起動時にambari apiをたたいてdatanode, nodemanagerを起動するようにしました。


kernelは3.10.0-514.2.2から3.10.0-862.9.1にあげました。

マシン再起動が必要で3台同時にやるとmissing blockになってジョブがこけるので多くても2台まで同時に作業しました。ここは完全に手動で温かみのある作業です。40台でだいたい4時間かかりました。

その後まだkernel panicが起きたのでkdumpを仕込みました。元々kdump自体はインストール済みだったので設定だけ少し変えて起動しときました。
どこを変えたかというとvmcoreはそれなりの容量になる気がしたので、OSとは別のパーティションに出力するように変更しました。

そしてkernel panicがまた起きてcrashコマンドでの解析を試みましたが、よくわからずcentosにissue登録しました。
0015216: 3.10.0-862.9.1.el7.x86_64 kernel panic and crash under hadoop environment - CentOS Bug Tracker

メッセージに

[exception RIP: find_busiest_group+869]

とあったのでfind_busiest_groupでググる
https://qiita.com/nhiroki/items/2fa7bb048118145b00cd
が見つかりずいぶん参考になりました。
負荷が高いときにスケジューラ周りのバグを踏んだんじゃないかという気がしますが、その後centos teamから返信がきて、最新のkernel 3.10-862.11.6を試してくれない?って言われます。
タイミング悪く3.10.0-862.9.1にあげた後にすぐ3.10-862.11.6が出たようです。
cpu hot plug関連でcpu core数が正しく表示されないbug 0015108: cpu core counts change unexpectedly - CentOS Bug Trackerが関係してそうでそれがkernel 3.10-862.11.6でfixされているとのことでした。

バージョン一覧がどこにあるのかよくわからんですが、例えば下記で見れるようです。
ftp://ftp.riken.jp/Linux/cern/centos/7/updates/x86_64/repoview/kernel-devel.html

3.10.0-862.9.1と3.10-862.11.6の差分は下記で見れます。
https://git.centos.org/compare/rpms!kernel.git/refs!tags!imports!c7!kernel-3.10.0-862.11.6.el7..refs!tags!imports!c7!kernel-3.10.0-862.9.1.el7

kernel upgradeのansible playbookはこんな感じで作りました。

    - name: chattr -i
      command: chattr -i /boot/grub2/grub.cfg

    - name: upgrade kernel
      yum: name=kernel state=latest

    - name: chattr +i
      command: chattr +i /boot/grub2/grub.cfg


3.10.0-862.11.6にあげても残念ながらkernel panicは起きました。ただメッセージは違いました。

 [exception RIP: __hrtimer_get_next_event+52]

その旨を報告すると、関連しそうな部分を直したものが含まれる3.10.0-862.11.6.el7.centos.plus.2を試してくれと言われます。

plus.1だったら

yum install --enablerepo=centosplus kernel-plus

とかすれば入りましたが、plus.2はkernel-plusにはないようなのでrpmで入れます。playbookはこんな感じ。

    - name: chattr -i
      command: chattr -i /boot/grub2/grub.cfg

    - name: install kernel-plus
      yum: name=http://.../kernel-plus-3.10.0-862.11.6.el7.centos.plus.2.x86_64.rpm state=present

    - name: grubby --set-default
      command: grubby --set-default=/boot/vmlinuz-3.10.0-862.11.6.el7.centos.plus.2.x86_64

    - name: chattr +i
      command: chattr +i /boot/grub2/grub.cfg

で、今は様子見中です。今までの頻度を考えると1週間何も起きなかったら解決したと思っていい気がします。