こんにちは @sonots です。Haikanko OSS化への道と称した Fluentd 連載第五回です。過去の記事はこちら
今回は連載第二回でちょっと言及した拙作 fluent-plugin-keep-forward プラグインと fluent-agent-lite に実装した KEEPALIVE_TIME オプションの紹介をしたいと思います。ある意味では前回の可視化の続編です。
困りごと
fluent-agent-lite でグラフを可視化していたら、30分に1回の頻度でデータが欠ける
fluentd (in_tail + out_forward) を agent として使ってホスト毎のグラフを作ると、値がバラバラになってしまう ※ 本来はこんなにギザギザにならないデータ。
fluent-agent-lite でグラフを可視化していたら、30分に1回の頻度でデータが欠ける
なぜそうなる?
第二回の記事 fluent-agent-lite と fluentd agent の比較(2) ~ Haikanko OSS化への道(2) でも書いたように、
fluentd の out_forward プラグインは heatbeat_interval (デフォルト1s) の周期でサーバの生死確認をしたのち Weighted Random で接続先のサーバリストを再作成します。実質データを送信するたびに別のサーバにつながります。
そのため datacounter などのプラグインで1分間 count++ しようにも別サーバにデータが送られしまって1箇所で合計値を出せなくなります。
fluent-agent-lite の場合は30分間同じ fluentd サーバにデータを送り続けますが、30分たったら再度ランダムに接続するサーバを選び直すロジックになっています。そのため30分に1回の頻度でグラフのデータが欠けてしまうわけです。
どう解決する?
以降、datacounter などのプラグインを動かしている fluentd サーバを worker と呼ぶことにします。
おそらく、本来あるべき姿の解決方法としては、
1. 全 worker の結果を別の fluentd に送って、そちらでホスト毎に合計値を出して GrowthForecast に投げる
だとは思うのですが、そのためには、***counter プラグインの結果を集計する counter × counter とでもいうようなプラグインを作る必要があって、さらにFluentd クラスタのアーキテクチャも変更しないといけなくなるので、もう1つ思いついた
2. agent を特定 worker につなぎっぱなしにする
というカジュアルな方法をチョイスすることにしました。つなぎっぱなしと言っても、もちろん、その worker プロセスが落ちた場合などは、別の worker に接続します。
fluent-plugin-keep-forward
ということで、1度接続したら同じサーバに送り続けるための out_forward プラグインの拡張として、fluent-plugin-keep-foward を作成しました。
使い方は、out_forward を継承して振る舞いを変えているだけなので、out_foward と全く同じです。なので、http://docs.fluentd.org/articles/out_forward を参照してください ^ ^;
例えばこんなかんじになりますね。第二回の記事からのコピーで、type forward が type keep_foward になっているだけです。
/etc/td-agent/td-agent.conf
<source>
type config_expander
<config>
type tail_asis
path /var/log/syslog
pos_file /var/tmp/_var_log_syslog.pos
asis_key message
tag raw.syslog_warn_app_name.${hostname}
</config>
</source>
<match **>
type keep_forward
send_timeout 60s
recover_wait 10s
heartbeat_interval 1s
phi_threshold 8
hard_timeout 60s
buffer_type memory
buffer_chunk_size 156
buffer_chunk_limit 8m
flush_interval 1s
retry_wait 1.0
retry_limit 17
<server>
name host1:22000
host host1
port 22000
weight 50
</server>
<server>
name host2:22000
host host2
port 22000
weight 50
</server>
<server>
name host3:22000
host host3
port 22000
weight 50
standby true
</server>
<secondary>
type file
path /var/log/td-agent/td-agent-failed.log
</secondary>
</match>
fluent-agent-lite の KEEPALIVE_TIME オプション
fluent-agent-lite でも keep-forward と同じ動きをさせたかったので、新しく設定を1つ追加して pull request させていただきました。
今までは30分という固定時間の間 keepalive していたのですが、その値が設定できるようになりました。そして、0 を設定すると(できるかぎり)ずっと同じサーバに接続し続けるようになります。
設定は例えばこんなかんじですね。最下行の KEEPALIVE_TIME=0 がポイントですね。
/etc/fluent-agent-lite.conf
# pre-process mkdir -p /etc/fluent-agent-lite cat <<"EOF" > /etc/fluent-agent-lite/primary_servers_list.conf host1:22000 host2:22000 EOF cat <<"EOF" > /etc/fluent-agent-lite/secondary_servers_list.conf host3:22000 EOF # configuration TAG_PREFIX=raw LOGS=$(cat <<EOF syslog.`hostname` /var/log/syslog fluent-agent.`hostname` /tmp/fluent-agent.log EOF) PRIMARY_SERVER_LIST=/etc/fluent-agent-lite/primary_servers_list.conf SECONDARY_SERVER_LIST=/etc/fluent-agent-lite/secondary_servers_list.conf LOG_PATH=/tmp/fluent-agent.log KEEPALIVE_TIME=0
結果
結果、こんなかんじでデータが欠けることなくグラフを作れるようになりました。やったね!
まとめ
agent を worker に永続接続させることで、データが欠けることなく可視化できるようになりました ^ ^
ただこの方法には、agent 起動時のランダム接続で偏りがでてしまった場合、それがそのまま継続してしまうという欠点があります。その点を少し心配していたのですが、実際に試してみた結果、さほど問題にならなかったのでOKかな~と思って使っています。あまりにも偏りが出た場合は、偏っている worker を一度落とせば再分配されますし、そもそもそういう状況に運用上、あまりなりませんでした。
ただこの方法には、agent 起動時のランダム接続で偏りがでてしまった場合、それがそのまま継続してしまうという欠点があります。その点を少し心配していたのですが、実際に試してみた結果、さほど問題にならなかったのでOKかな~と思って使っています。あまりにも偏りが出た場合は、偏っている worker を一度落とせば再分配されますし、そもそもそういう状況に運用上、あまりなりませんでした。
とはいえやはり欠点は欠点なので、将来的には「1. 全 worker の結果を別の fluentd に送って、そちらでホスト毎に合計値を出して GrowthForecast に投げる」のアプローチを取る予定でいますが、とりあえずカジュアルにやるには良いアプローチだと思ってやっています。
それでは!