tkuchikiの日記

新ブログ https://blog.tkuchiki.net

fluentd の out forward の secondary を S3 にして信頼性を向上する

オートスケールするサーバ(web、アプリ)に立てている fluentd(以下、sender) から、
ログ集約用の fluentd(以下、aggregator) にデータを送るとき、
aggregator がデータを受け付けられないと sender で buffer すると思います。
この状態でスケールイン(ディスクごとサーバを削除)すると、
buffer していてもデータをロストしてしまいます。
そこで、sendor から aggregator に送れない場合は Amazon S3 に送ることができたのなら、
信頼性を向上できるのではないかと考え実験しました。

検証環境

  • fluentd 0.12.22
  • fluent-plugin-s3 0.6.6
  • ruby 2.3.0

注意点

sender から aggregator にデータを送れない状況を再現するために、
server には fluentd を起動していないホストを指定します。
存在しないホストを指定すると fluentd の起動に失敗するので、存在するホストを指定してください。

file buffer

buffer したデータを比較するため、まず file buffer の実験を行います。
以下の様な設定ファイルで fluentd を起動します。

以下の様に fluent-cat でデータを送ります。

$ echo '{"foo": "bar"}' | fluent-cat debug.test

buffer は msgpack なようなので decode するスクリプトを用意しました。

decode すると以下の様になります。

$ ruby unpack.rb /path/to/forward.debug.test.xxx.log
[1459155557, {"foo"=>"bar"}]

s3 buffer

次は S3 に buffer できるかの実験です。
以下の様な設定ファイルで fluentd を起動します。
実験のため、retry_limitmax_retry_wait を非常に短くしています。

起動できたら file buffer の時と同じようにデータを送ります。

$ echo '{"foo": "bar"}' | fluent-cat debug.test

S3 を見るとデータが保存されていました。
送れていることが確認できたのならば、file buffer のときと同じく復元できるか確認します。

$ aws s3 cp s3://path/to/buffer/forward_debug.test.gz .
$ gunzip forward_debug.test.gz
$ ruby unpack.rb /path/to/forward.debug.test
[1459155737, {"foo"=>"bar"}]

復元できました。
タイムスタンプ以外は同じ結果になったので、
aggregator を復旧すれば buffer からデータを再送できると思います。

まとめ

out forward の secondary を S3 にすることができるか検証しました。
検証に使った設定ファイルのままでは使えないと思いますので調整する必要はあると思いますが、
buffer をロストしにくくできそうですね。
実際に使用する場合は、S3 の buffer からデータを送り直す手順を確認しておくと良いと思います。
primary と secondary の type が違うのは推奨していないようで、
type of secondary output should be same as primary output primary="Fluent::ForwardOutput" secondary="Fluent::S3Output" のような warn が出力されます。
secondary を S3 にした場合は問題なさそうな挙動でしたが、
他の plugin ではどうなるかわかりませんのでご注意ください。