2017/2/28 18:15~21:15あたりまでエラーが多発していました。ご迷惑をおかけしてしまいました。
久しぶりにサーバが落ちるほどの障害を起こしてしまいました。。。原因とその対策のログです。
直接の原因はサーバのメモリ不足
CopyContentDetectorはサーバ20台前後で運営しています。負荷の掛かる処理はAPIサーバみたいのを構築して並列で実行する方式を取っています。今回は、APIサーバ2台がメモリ不足になっていました。結果そのサーバがひたすらスワップアウトしまくって、レスポンスがガタ落ち→死亡→更にOOM Killerまで動いてサーバ再起動。という流れでした。
冗長化してるのですが、うまく切り離してもらえなかったみたいです。
何で急にメモリ不足が起こったのか
調べて見た結果、最近DBサーバサーバ入れ替えて、パラメータのチューニングやインデックス、その他もろもろ調整したのが要因でした。結果、DBからのレスポンスがとても早くなったのです。
ですが、結果として処理できる量が多くなって、今度はAPI側に負荷がかかるようになった。という流れです。
【対策1】mod_proxy_balancerの設定を見直し
APIサーバ復数をmod_proxy_balancerを利用してAPIを負荷分散、及び冗長化しています。どうにも設定が良くなかったみたいで不良なサーバをタイムタウトで切り離してくれなかったみたいです。もう一回設定見直して、全体を変更してみました。
BalancerMember http://192.168.0.5 loadfactor=10 retry=5 connectiontimeout=30 timeout=30
BalancerMember http://192.168.0.7 loadfactor=10 retry=5 connectiontimeout=30 timeout=30
.......たくさん続く
ProxySet failonstatus=500,403,404
接続30秒出来なかったらエラー、タイムアウト30(通信が5秒以上途切れたら)エラー。と言うようにタイムアウトを更に短くしました。また、failonstatusを設定して、レスポンスコードでもエラーを設定するようにしました。
説明は、こちらのサイトがとてもわかり易かったです。
きっと大丈夫。
【対策2】swapなんていらないんじゃないか
結局swap起こしてAPIが正常に動かないなら、swap領域を減らしてOOMKillerでさっさと再起動したほうが良いのではないかと思いました。今回のようなそれなりに悲しい障害には発展しにくいはずです。以下のような設定を行いました。
swap領域を減らす
以下のコマンドで減らしました。Conohaのswap領域はLVMなので、簡単に容量を減らすことが出来ました。これで、200MBのSWAP領域になりました。
swapoff -a
lvreduce -L 200M /dev/VolGroup/lv_swap
mkswap /dev/VolGroup/lv_swap
swapon /dev/VolGroup/lv_swap
OOMKiller起こったら再起動設定
/etc/sysctl.confに以下を記述します。これでOOMkillerが走るとそのままサーバが再起動します。
vm.panic_on_oom = 1
sysctl -pをして読み込みます。
【対策3】Apacheのメモリの確認
確認してみました。どうやら1プロセスあたり17MBくらい利用しているようです。なので、バッチとAPIが混成しているサーバは10個、API専用サーバは25個起動するようにしました。更にMaxMemFreeをつけてメモリの開放をしやすくしました。このMaxMemFreeの説明は以下のサイトがわかりやすいです。
<IfModule prefork.c>
StartServers 10
MinSpareServers 10
MaxSpareServers 10
ServerLimit 300
MaxClients 300
MaxRequestsPerChild 4000
MaxMemFree 2048
</IfModule>
Apache周りのチューニングはメモリ消費量の調整としました。
これでしばらく様子を見てみようと思います。今後共CopyContentDetectorをよろしくお願いいたします。