ネットワーク起因で真の Split-Brain 障害発生

今までも何度か扱ってきたSplit-Brain問題。うちの環境で起き得るのは、マルチマスターになっているGlusterFSやMariaDB、ElasticSearchなど。これまで経験したSplit-Brainは、そうは言いながらも片側のみ更新されて、もう一方が更新されないというもの。正しく更新されている方にキャッチアップさせればいいだけなので、それほど難易度は高くない。あるいはSplit-Brain対策で書き込み停止してしまったサービスをどうするか、というものもあったかもしれない。真の意味でのSplit-Brainを経験することはなかった。

では、真のSplit-Brainとは何かと言うと、分断されたクラスターがそれぞれにマスターになってしまって、別々の更新を受けてしまうこと。こうなってしまうと、それぞれのクラスターに行われた更新を整合性を考慮しつつ、おそらくは手動で修正していく必要がある。我が家の環境はたかだか2台のサーバ構成だし、まさかSplit-Brainが起きるとは思っていなかったし、むしろSplit-Brain予防のための書き込み防止が邪魔だなと感じていたくらい。しかし、その日はやってきた。

クラスターが分断してしまうのは、そのほとんどがネットワーク起因だろう。実は以前にkernel4系を試した際に気付いたのだが、デフォルトでNICのオフロード機能が有効になり始めている。LinuxではTSO(TCP Segmentation Offload)と呼ばれる機能に当たる。これがCentOSでも7.2からデフォルトで有効になったようだ。なぜ、このような細かい点に気付いたかといえば、このTSOが有効だと突然NICが落ちることがあるからだ。気付いてからは明示的にオフるようにしていたのだが、ホストOS上では物理NICをブリッジ化していて、ブリッジデバイスは無効化していなかったせいか再発してしまった。

NICのダウンがたまたま1号機で起きてしまったため問題はややこしくなった。zabbixのfailoverもうまくいかなかったようで障害通知は届かず、しばらくダウンには気付かなかった。翌日、録画した番組を見ようとKODIを見るが、レジューム状態が正しく表示されない。これはもしやとepgrecを見ると500番のエラー。このパターンはmariadbがSplit-Brain予防で参照できなくなったと予想が付く。1号機にはsshもpingも通らない。コンソールを繋いでみると元気に生きていて、『e1000c detected hardware unit hang』みたいなエラーが出力され続けていて、TSOの問題だとわかる。

1号機を起動して回復処理を行う。hadoopは勝手にunder repliが解消した。優秀。mariadbはクラスターを解体しないと起動できないので、『wsrep_cluster_address=gcomm://』という設定で1台起動。1台目を参照する形で2台目を起動させ復活。念のため、1号機もwsrep_cluster_addressを元に戻して再起動。elasticsearchは手前のtd-agentを冗長化していなかったので問題なし。うーん、怠惰な自分に助けられたw 最後に最も手間取るGlusterFSを見てみると、案の定Split-Brainが起きていた。

GlusterFSのSplit-Brainは慣れたものとデータを確認してみると、ちょっといつもと様子が違う。大体2台とも同等の動作をするように作っているのだが、録画処理などは1号機がマスターとなって動作する。そして録画処理はネットワークがダウンしてもチューナーさえ繋がっていれば動作し続ける。つまりネットワーク的にはダウンしたものの、OSは生きていてスタンドアロンな状態で録画処理は継続していた。そして、その録画データは同じノードにあるGlusterFSのbrickに書き込まれてしまっていた。

一方の2号機は、keepalivedが1号機のダウンを検知して、録画処理を昇格させる。こちらでも当然録画処理を実行され、その録画データをGlusterFSのもう一方のbrickへ書き込んでしまう。つまり非常に似ているデータではあるが、それぞれのbrickが異なる録画データを持つ形になっていたのだ。録画データはそれほど多くないので1つ1つ確認していけば正しく復旧はできるが、起きる訳がないと思っていた真のSplit-Brainがこんな小さい環境で起きたことのショックが大きい。

今回の問題はTSO有効化によるNICダウンが直接の原因。まずはブリッジデバイスのTSOを無効化にする以下のコマンドをrc.localに追加した。

ethtool -K eth0 tso off
ethtool -K br0 tso off

これでNICダウンが再発しないことを願う。しかし、一方でkeepalivedのSplit-Brain対策がなされていないことも、もう1つの問題のように思う。ヘルスチェック時に何らかの形でzookeeperを利用するなど、quorumを意識した疎通確認を加えたい。単純な第3者へのping確認とかにしてしまうと、そのノードが落ちた時に全滅してしまう可能性が怖い。できればリソースを3重化したくない自分が、hadoopのために泣く泣く3台運用しているzookeeper。これをうまく活用したいものだ。

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)