Fluentdの所感 その1

Fluentdをある程度触ったので、書きなぐったメモをおこしておきます。

少し多いし、今後もまだ触るので小分けしておきます。



冗長化と負荷分散

最初の構成はこんな感じ。あとあと保存先はHDFS以外も増やすかもしれません。

Agent

ログの量やFluentd&CPUの性能を考えると、負荷的には1サーバ1Agentで十分足りるので、ステータス検知などの監視だけしっかりしておけばOKと考えます。なので例えばWEBサーバに普通に1Agent入れてそれが数百・数千台になることを想定します。

Collector

複数台用意し、Agentからroundrobinで送信することで均一化します。Collectorダウン時や復旧時は、ログのロスト無しにすみやかにroundrobinから外れたり復活することを確認済みです。台数が増えすぎた時の懸念点は、HDFSに対する1ファイルへのAPPEND数が増えることですが、ここまでの試験を見る限りはおそらくかなりの数まで大丈夫ですし、仮にHDFSへの書き込みが問題になる場合はAgent -> Collectorの選択条件や、書き込みファイルパスで工夫すれば大丈夫です。

とはいえ、APPEND非推奨の話もあるのでメモ。
  • Known Issues and Work Arounds in CDH3
  • HADOOP-8230 – Apache.org – The Apache Software Foundation!
  • Append機能の概要

  • HDFS

    NameNodeが落ちてもCollectorでログを確保してくれて、復旧してSafemodeが終わればロスト無しに再送してくれるのを確認済みです。HadoopのMasterNode冗長化とかは別の話なので省きますが、このくらいなら数秒のフェイルオーバーが発生しても大丈夫っぽいです。

    大丈夫:どの部分もダウンすることを前提とし、素早い検知と復旧を経てログのロストがないこと


    Collectorのキャパシティ限界対策

    Collector自体は増やせばいいですし、なかなか限界はこないようにしておきますが、もし限界がくるとAgentのForward先の設定を変更しなくてはいけなくなります。Agentは様々なアプリがあって、様々な部署が管理していたり、もしかしたら社外の管理下にある場合も想定すると、なかなか全Agent管理者に対して
    『Collector増やしたのでAgent設定を更新してfluentdを再起動してください』
    とは言えません。

    かと言って、設定をHTTPでincludeするのも、そのHTTPサーバを丈夫にする手間が発生するのでやりたくありません。

    なので、例えばCollector5台から始めたとして、増やさざるをえない時がきたら、別途Collectorを10台用意し、元のサーバにはLVSと入れ替えて新CollectorにDirectRouting分散すればほぼ解決するかなと思います。LVSはfluentdよりはるかにリクエスト数を捌け、安定しているからです。最初からLVSにするかは場合によりけりで。

    Fluentd Agentのアプリへの影響

    アプリとは同居するWEB/APなりのRubyやPHPのことですが、fluentdプロセスは1OSにつき1vCPUしか利用できないため、最大でも 1vCPU 100% までしか影響しません。今の時代に 1vCPU なんてサーバはないでしょうからよほどスペッシャルなプラグインでも入れない限り大丈夫でしょう。

    1vCPU : どう表現するかの問題ですが、vCPUというと仮想環境臭が漂いますが、物理サーバでの 1thread とも同じ意味で使っています。何が一番わかりやすいやら


    HDFSへの書き込み

    FlumeだとAPPENDを嫌ってか、1Collector : 1HDFSファイル という形になり、書き込み完了前は .tmp ファイルになるという特性があります。Fluentdの fluent-plugin-webhdfs だと、複数Collector : 1HDFSファイル のAPPENDスタイルになるので、path に

    と指定すると、確実に1分につき1ファイルになってくれます。APPENDは圧縮できないのと、限界に微不安がある以外は幸せしかないと思います。

    また、HDFSに限らない話ですが、pathの日時部分はなんのtimstampを元に生成されるかですが、例えばAgentでtailを使っていたとすると、tailがそのログを読み込んだ日時を元に生成されます。つまり、何かしらの障害が発生してログ読み込みや再送を再開した時に、新しくtailで読むログは、ログがどれだけ古くとも再開した新しいtimestampが使われ、既にBufferに取り込まれたログの再送は取り込み済みの古いtimestampで path に書き込まれることになります。

    この辺は、一次生ログがログローテート式なのか日時パス式なのかとか、HDFSに入った後の処理はなんなのかとかによって、特性をうまく吸収していけばいいんじゃないかと。

    Agentのインストール方法

    Collectorは集約するところなのでOSは好きにできるし、入れてしまえばしばらく放置なのでいいのですが、Agentは色んな管理者にインストールしてもらったり、色んなOSがあったり、サーバ増設が頻繁にあると想定すると、できるだけシンプルにまとめる必要があります。少なくとも、既にRuby on Railsが動いているサーバのRubyを共有で使うなどありえません。

    とすると、RVM+gem か td-agent になるのですが、td-agentが今の質を保ってくれるならばtd-agentでいいと思います。Debianならapt、CentOSならyumでインストールするまでは異なりますが、それ以降はほぼ同じになるので。RVMだとインストール時間が長かったり、その対策としてパッケージ化うんぬんとかやると面倒ですしね。

    独自プラグインのgemは迷っていますが、公開するか、社内gemか、原始的にインストール手順とgemファイルをセットで配るか・・・この辺は何人かアプリ管理者に聞いて調整って感じかなと。

    プラス、ログの送信状態を監視するためにmonitやnagios-nrpe-serverなどもセットで完成。


    次回は独自プラグインや負荷試験、監視などについて触れたいと思います。