fluentdでマルチコアのサーバーリソースを生かすため、fluentdのmultiprocessプラグインを導入することにした。multiprocessプラグインについては、以下の公式ドキュメントに書かれているとおりに設定すれば、無事複数プロセスを起動することができる。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<source> type multiprocess <process> cmdline -c /etc/td-agent/td-agent-child1.conf sleep_before_start 1s sleep_before_shutdown 5s </process> <process> cmdline -c /etc/td-agent/td-agent-child2.conf sleep_before_start 1s sleep_before_shutdown 5s </process> </source> |
ただ、今までの設定を複数プロセスから共通で使うように指定したい場合には注意が必要かと思う。例えば、out_file
などを使っていて、うっかり以下のようにすると複数プロセスからの同一ファイルへの操作が発生してしまう。
1 2 3 4 5 6 |
# /etc/td-agent/td-agent-child1.conf <source> type forward port 24224 </source> include conf.d/common.conf |
1 2 3 4 5 6 |
# /etc/td-agent/td-agent-child2.conf <source> type forward port 24225 </source> include conf.d/common.conf |
1 2 3 4 5 |
# conf.d/common.conf <match access_log> out file path /data/fluentd/access_log </match> |
これについては、以下のページでも言及されているように、同一ファイルへの指定は避けた方が良い。
何故なのか、理解を深めるために備忘録を含めソースを追ってみる。(バージョンは、v0.10.39、間違ってたらすみません)
まず、上記でも言及されているように、out_file
は設定ファイルの指定ごとにFileOutput
オブジェクトで管理される。FileOutput
クラスは、BufferedOutput
を継承しているので、送られてくるデータはバッファにたまり、BufferedOutput
のOutputThread
によるループのサイクルでフラッシュされる(チャンクはキューに入り、最終的にファイルへ書き出される)。
FileBuffer#resume
を見ると、fluendの起動時、FileBuffer
(BasicBuffer
を継承している)はpath文字列を元に既存のバッファファイルを探し、バッファファイルが見つかれば、chunkのkeyとchunkからなるマップを生成する。仮に、out_file
による同一のpath指定が存在し、タイミングによっては前回停止時のバッファファイルが複数存在している場合、生成するマップのkeyが重複するため、一方のバッファはマップから漏れてしまうこともある。また、同一のバッファファイルを参照している時、フラッシュのタイミングによっては、バッファをキューに入れる際のrename
の処理で失敗し、知らない間にOutputThread
が死んでしまっていることもある。
1 |
access_log.20140801.b4ffb8eca05e09216 <--- resumeでこのバッファファイルを複数のout_fileが参照してしまった場合。 |
access_log.20140801.b4ffb8ecb73040f17
しかし、同じプロセスであれば、FileBuffer
のクラス変数@@buffer_paths
で重複パスが存在している場合、fluentdの起動時の処理でConfigError
がraiseされpathの重複は報告されるようになっている。(コミット:fbcfaa7
)
また、webhdfsでHDFSへ書き込んでいる場合にも、同一ファイルに対しての複数のHTTPリクエストが発生するので、注意が必要かと思う。
ということから、multiprocessで複数プロセスで処理するときには、設定を慎重に行なう(当たり前と突っ込まれそうだが)必要がありそうだ。
コメント