こんにちは @sonots です。Haikanko OSS化への道と称した Fluentd 連載第五回です。過去の記事はこちら 今回は連載第二回でちょっと言及した拙作 fluent-plugin-keep-forward プラグインと fluent-agent-lite に実装した KEEPALIVE_TIME オプションの紹介をしたいと思います。ある意味では前回の可視化の続編です。

困りごと

fluentd (in_tail + out_forward) を agent として使ってホスト毎のグラフを作ると、値がバラバラになってしまう ※ 本来はこんなにギザギザにならないデータ。
 fluentd











fluent-agent-lite でグラフを可視化していたら、30分に1回の頻度でデータが欠ける
fluent-agent-lite








 


なぜそうなる?


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

結果

結果、こんなかんじでデータが欠けることなくグラフを作れるようになりました。やったね!
keep-forward










まとめ

agent を worker に永続接続させることで、データが欠けることなく可視化できるようになりました ^ ^

ただこの方法には、agent 起動時のランダム接続で偏りがでてしまった場合、それがそのまま継続してしまうという欠点があります。その点を少し心配していたのですが、実際に試してみた結果、さほど問題にならなかったのでOKかな~と思って使っています。あまりにも偏りが出た場合は、偏っている worker を一度落とせば再分配されますし、そもそもそういう状況に運用上、あまりなりませんでした。 

とはいえやはり欠点は欠点なので、将来的には「1. 全 worker の結果を別の fluentd に送って、そちらでホスト毎に合計値を出して GrowthForecast に投げる」のアプローチを取る予定でいますが、とりあえずカジュアルにやるには良いアプローチだと思ってやっています。

それでは!