fluentdのAggregatorをELBで負荷分散し、Blue/Green Deploymentする

fluentdaws

デプロイやスループットの調整を簡単にするため、BeanstalkでAggregatorを立ち上げた。

負荷分散

TCPの24224(設定による)が通るようにEC2,ELBのSGとリスナーの設定をする必要があって、 ELBのSGのアウトバウンドの設定が見落とされがち。ELBのクロスゾーン分散は有効になっている。

まず、ELBに3台、それぞれ別のAZ(1b, 1c, 1d)に配置されている状態でログを送り始めるとそれぞれ均等にログが届いた。 その状態から4台(1b * 2, 1c, 1d)にすると、2つのインスタンス(1b, 1c)のみに均等にログが届くようになった。 4台になると(1b, 1c)と(1b, 1d)に分けられてELBのノードがそれらの組に紐づいたということだと思う。 各ノードにはDNSラウンドロビンするようになっている。実際restartすると今度は別の組の方に送られた。

では、なぜ一度送り始めると同じ方にしか飛ばないかというと、forwardプラグインのexpire_dns_cacheがデフォルトでnilになっていて、 heartbeatが届いている間は無期限にDNSキャッシュするようになっているため。これに0(キャッシュしない)か秒数を指定すると、 その間隔で他の組のインスタンスにもログが届くようになった。 expire_dns_cacheしなくても複数のインスタンスからラウンドロビンされるため全体でいえば分散される。

heartbeat

ELB配下のEC2を全て落としてもheartbeatに失敗しないため、standyに移行せずELBのバックエンド接続エラーになってログがロストしてしまうようだ。 ログにも出ず、以下のようにactive-standbyの設定をしてもstandbyに移行しない。 全てのインスタンスが同時に落ちるというのは滅多に起きないだろうが、少なくとも検知できるようにはしておく。

<server>
    name td1
    host autoscale-td1.us-east-1.elasticbeanstalk.com
    port 24224
</server>
<server>
    name td2
    host autoscale-td2.us-east-1.elasticbeanstalk.com
    port 24224
    standby
</server>

Blue/Green Deployment

Blue-Green Deploymentというのは、2つの系を用意し、activeでない方にデプロイし、 スワップして反映させるもの。ダウンタイムなしで問題が起きた際にもすぐに切り戻すことができる。 スワップして向き先を変えるにはexpire_dns_cacheを設定する必要がある。

Auto Scaling

増えるのはいいとして減るときに、 送り先で一時的に障害が起きていたりするとバッファをflushできずにログがロストする可能性がある。 それでいうとログの送り元でも同じことが起こりうるんだが、通常Aggregatorにしか送らないので比較的問題になりにくい。

これを避けたい場合、Auto Scalingグループの設定で スケールインから保護を有効にして これから立ち上がるインスタンスはスケールインしなくすることができる。 それまでに立ち上がっていたインスタンスには適用されないので注意。

スケールインしないということは最大の台数で止まってしまうので、 ピークを過ぎたらスワップしてバッファが全て掃けたことを確認してからTerminateすることになる。 これを日常的にやるのは面倒なので、実際は予期しない流量の増加に備えて一応設定しておき、 普段はしきい値にひっかからないような最低台数で待ち構えておくことにするかな。

あとはヘルスチェックによって潰される可能性はなくもないが、それはもうやむなし・・・。

参考

AWS ELBの社内向け構成ガイドを公開してみる 負荷分散編 – Cross-Zone Routingを踏まえて | Developers.IO