2013年04月

Haikanko OSS版をリリースしました!〜 Haikanko OSS化への道(8)

こんにちは @sonots です。Haikanko OSS化への道と称した Fluentd 連載のなんと最終回です!過去の記事はこちら

本日は、Haikanko OSS版をついにリリースしましたので正式にお知らせします!こちらにおいてありますので、是非 fork して遊んでみてください!まだユーザーマニュアルがないのでちょっとアレゲなんですが、近日中に用意しますのでご容赦を。

https://github.com/sonots/haikanko


Issue にも積んでいるように、本当はまだまだデプロイのテスト(serverspec 使いたい!)とか、fluentd クラスタの integration テスト(fluentd-integration が使えそう!?)とか、やりたいことは色々あるのですが、

とか色々思う所あって、とりあえず出すことにいたしました!

ご意見、ご感想、プルリクお待ちしていますのでよろしくおねがいいたします!



ということで早速 @tagomoris 先生に twitter でご感想いただいていたのでそのやり取りをば。

うーん、そうですね。Haikanko はフレームワークではなく、アプリという立ち位置なので、すでに Fluentd の環境を構築している @tagomoris 先生のような状況だとちょっと適用しづらいかと思います。


ということで、haikanko framework なんてのも出したいとは思っているのですが、今ココってかんじですね。

この辺は認識していて、ギッハブの Issue にも登録してあります。chef を使うなどしてお試し環境ぐらいはさくっと立てられるようにしたいですね〜。プルリクお待ちしています><


それでは!


minaについてそろそろ語っておくか 〜 Haikanko OSS化への道(7) #shibuyarb

こんにちは @sonots です。Haikanko OSS化への道と称した連載第七回です。過去の記事はこちら先日の shibuyar.rb で、Haikanko の中で使っている mina (shibuya.rb 的にはミーナと呼ぶことに決まりました^^) というデプロイツールについて語ってきたので発表資料をおいておきます。

Haikanko ではこの mina というツールを使って Fluentd クラスタのデプロイを実現しています。Haikanko を実装しはじめてから、かれこれ3ヶ月ほど使い込んでノウハウなどがたまってきたので、まとめということでお話してきました。

当日の様子は @fukayatsu さんが togetter をまとめてくれたのでそちらを見るとよいかと思います http://togetter.com/li/489435

個人的にはシェルスクリプト脳な所が気にいっていて、「シェルスクリプトは最強のDSL」と豪語する一般的なインフラエンジニアの方々にとってはとっつきやすいのではないかと思っています。あとは、capistrano と比べて小さいツールなので、不可思議な動きをされたときにコードを追いやすい、というのもありますね。

そんなかんじで、mina と Haikanko をよろしくお願いいたします。
#Haikanko公開の話はまた別途 :D

それでは! 

Fluentdでログ収集 〜 Haikanko OSS化への道(6)

こんにちは @sonots です。Haikanko OSS化への道と称した Fluentd 連載第六回です。過去の記事はこちら
今回は Haikanko が提供する1つのフィーチャー(SIer 的に言うソリューション!)であるログ収集の機能についてお話したいと思います。

やりたいこと

簡単にいうと syslog-ng の代わりに使いたい。つまり
  • アプリサーバのログを転送して、そのままログ保存サーバのファイルシステム(実際はNFSかもしれないし、そうじゃないかもしれない)に保存したい
  • ログ保存サーバが1台だと不安なので、レプリケーションしておくりたい
実現方法

fluent-agent-lite を agent として利用する場合は、fluent-agent-lite にはレプリケーションして複数サーバに送る機能はないので、1度別の fluentd ノード (deliver と呼ぶことにします)に送って、deliver で out_copy プラグインを使ってレプリケーションした上で、ログ保存の fluentd ノード (archiverと呼ぶことにします)に送信する形になります。

62d23f20.jpg

fluentd を agent として利用すると (便宜上、sender と呼ぶことにします)、out_copy プラグインを利用してログをレプリケーションして複数 archiver に送ることができるようになります。

8c2a246a.jpg

Haikanko では deliver ノードを用意するのが面倒だったので、 後者のアプローチを取ることにしました。

アプリサーバのネットワークトラフィックが archiver の数だけ倍になっているので、アプリサーバに負担をかけたくない場合は、前者の fluent-agent-lite の仕組みのほうがよいのかもしれませんが、deliver ノードにトラフィックが集中するのもどうかなぁ、と思ってこうしています。置き換え対象の syslog-ng も後者のアーキテクチャだったので、同じ仕組みなら問題ないだろうという算段もありました。

設定ファイル(sender)

fluent-agent-lite と fluentd agent の比較 で書いた fluentd agent とほとんど同じなのですが、負荷分散の代わりに out_copy を利用してレプリケーションした上で、out_forward プラグインで複数サーバにデータを送信するようにしています。

<source>
  type config_expander
  <config>
    type tail_asis
    path /var/log/applog
    pos_file /var/tmp/_var_log_applog.pos
    asis_key message
    tag raw.applog.${hostname}
  </config>
</source>
<match **>
  type copy
 
  <store>
    type forward
    flush_interval 1s
    <server>
      host host1
      port 24000
    </server>
  </store>
 
  <store>
    type forward
    flush_interval 1s
    <server>
      host host2
      port 24000
    </server>
  </store>
</match>


設定ファイル(archiver)

tagomoris  先生のFluentdでログ収集「だけ」やる話 を参考に fluent-plugin-file-alternative を利用して実現しています。fluentd 標準の out_file プラグインだと、タグや時間が付いたり、出力がJSONになってしまったりと(今回のケースでは)余計なものが付いてしまいますが、fluent-plugin-file-alternative を使うと受け取ったログ行だけ出力できます。簡単ですね!
<source>
  type forward
  port 24000
</source>

<match raw.applog.**>
  type file_alternative
  path /var/log/applog.%Y%m%d
  output_include_time false
  output_include_tag false
  output_data_type attr:message
  add_newline true
  compress gz 
</match>

と思っていたのですが、以下の設定のように、
<source>
  type forward
  port 24000
</source>

<match raw.applog.**>
  type file_alternative
  path /var/log/applog.%Y%m%d
  output_include_time false
  output_include_tag false
  output_data_type attr:message
  add_newline true
  compress gz 
</match> 

<match raw.applog2.**>
  type file_alternative
  path /var/log/applog.%Y%m%d
  output_include_time false
  output_include_tag false
  output_data_type attr:message
  add_newline true
  compress gz 
</match> 

タグは違うけれど(raw.applog と raw.applog2)、保存先の path が同じ、という設定を書いてしまった場合に、
$ ls /var/log/ | grep applog
/var/log/applog.yyyymmdd.20130412.b4da171215ae3fdd3.log
/var/log/applog.yyyymmdd.20130412.b4da172062a515bb2.log
のように一時ファイルが2つ作られてしまい、rename の処理でエラーが出たり、最終的に /var/log/applog.20130412.gz と  /var/log/applog.20130412.0.gz という2つのファイルに分かれて保存されてしまうといった現象が発生してしまいました。

これはどうも fujiwara 先生のfluentdで複数箇所から同一のファイルに出力するで既知の問題だったようで、そこで解決方法を真似して fluent-plugin-rewrite を利用して、同一のファイル出力する file_alternative 設定は1箇所だけになるように調整しています。

こんなかんじですね。※ タグにパスそのまま入れて動いているんですが、これってアリなんですかね?
<source>
  type forward
  port 24000
</source>

<match raw.applog.**>
  type rewrite
  add_prefix /var/log/applog.%Y%m%d
</match>

<match raw.applog2.**>
  type rewrite
  add_prefix /var/log/applog.%Y%m%d
</match>

<match /var/log/applog.%Y%m%d.raw.**>
  type file_alternative
  path /var/log/applog.%Y%m%d
  output_include_time false
  output_include_tag false
  output_data_type attr:message
  add_newline true
  compress gz
</match>

まとめ

こんなかんじでログ収集ができるようになりました。

Haikanko としては、設定項目から sender と archiver の設定ファイルをループでまわして自動生成してデプロイしているかんじですね。

それでは!

fluent-agent-lite と fluentd の keepalive 〜 Haikanko OSS化への道(5)

こんにちは @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 に投げる」のアプローチを取る予定でいますが、とりあえずカジュアルにやるには良いアプローチだと思ってやっています。

それでは!

FluentdとGrowthForecastを使った可視化 〜 Haikanko OSS化への道(4)

こんにちは @sonots です。Haikanko OSS化への道と称した Fluentd 連載第四回です。過去の記事はこちら

今回は前回解説したログ監視機能に加え、Haikanko が提供するもう1つのフィーチャー(SIer 的に言うソリューション!)である可視化の機能についてお話したいと思います。

結構よく聞く構成なので、あまりブログに書く必要はないような気もしますが、連載という形でまとめたいので書いておきます。

やりたいこと
  • アプリケーションログのステータスコード(2xx, 3xx, 4xx, 5xx)の1分あたりの数をグラフ化したい
  • アプリケーションログのレスポンスタイム(<1sec, <2sec, <3sec, <4sec, >=4sec)の1分あたりの数をグラフ化したい
  • 1分間の平均レスポンスタイム、最悪(最大)レスポンスタイムをグラフ化したい
  • これらのグラフをホスト毎に出したい
というのを Fluentd + GrowthForecast でできる所までやります。レスポンスタイムをグラフ化したい、というのは5秒ルールがあるソシャゲ業界っぽくてアツいですね。
続きを読む
A Ruby and Fluentd committer working at DeNA. 記事本文および記事中のコード片は引用および特記あるものを除いてすべて修正BSDライセンスとします。 #ruby #fluentd #growthforecast #haikanko #yohoushi #specinfra #serverspec #focuslight
はてぶ人気エントリー