Fluentdが障害の時にどのような動作をするのか調べてみたので、そのメモ. td-agent 1.1.17(fluentd v0.10.39)で確認したつもりだが、もしかしたらもう少し新しいので確認したケースもあるかも. BufferedOutputを中心に記載している.
BufferdOutputの基本
fluentdの特徴の一つとして、fluentd送信先で障害があり、メッセージが送れなかった場合は大抵(BufferedOutputを使っているプラグインであれば)fluentdでバッファリングし、一定時間後に再送してくれる.
このバッファリングのサイズは、BufferedOutputプラグインのbuffer_chunk_limit*buffer_queue_limitで決まる.
これらのデフォルト値は以下に解説付きでまとまっている. (良く参照させて頂いています) FluentdでバッファつきOutputPluginを使うときのデフォルト値
何回くらいリトライするの? リトライの間隔は?
リトライの回数は、retry_limit(デフォルト 17)で指定された回数まで. 間隔は一定ではなく、段々延びていく. 具体的に間隔を計算してるのは、BufferedOutput#calc_retry_wait.
リトライ間隔は、以下のパラメータでコントロールすることができる
- max_retry_wait(デフォルト: nil = 上限なし)
- retry_wait (デフォルト: 1.0)
同じメソッドを使って、実際にどれくらいになるのかを計算させてみた. 以下で例えば、1=>2は、一度送信に失敗してから、2回目の送信を試みるまでという意味. 単位は秒. 全てデフォルト値だと、以下の様な感じ. 最大だと、33765秒=9時間22分になる.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
例えば、max_retry_wait=120とすると、以下のようになる. 何回リトライしても、リトライ間隔の上限はmax_retry_waitまでになる.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
retry_waitを半分の0.5にすると、全てのリトライ間隔が半分になる.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
リトライの頻度を増やす(リトライ間隔を減らす)場合は、併せてretry_limitも変更しないと、早々にリトライアウトしてしまう、ということになるので注意.
リトライ回数が超過したら?
リトライ回数を超過した場合、secodaryディレクティブを指定しておけば、そちらに出力される. 通常は、ファイルに出力しておいて、後からリカバリに使う、というケースが多いと思う.
1 2 3 4 |
|
このようなケースでは、ログに以下のように出力される
1
|
|
キューが溢れたら?
キュー(バッファ)が溢れると、fluentdのログに以下のようなメッセージが出る.
1
|
|
この場合、inputプラグインがEngine.emitを実行する際にExceptionが発生する. プラグインが、これをrescueしていない場合、inputプラグインは停止する. rescueしている場合はinputプラグインの実装次第だが、大抵Exceptionは無視されてemitしたデータは破棄される. (既に溜めるためのキューがあふれているので、それしか無い)
送信先が復活したら?
再送中に送信先が復活し、再送に成功した場合は以下の様なメッセージが出力される.
1
|
|
ここで、注意点として送信先が復活してもすぐに再送してくれるわけではない. これは、送信先とのハートビートを行っているout_forwardでも一緒. BufferedOutput#try_flushのコードを見ると分かるが、リトライ中で、まだ次のリトライ時刻に達していない場合は、送信は行わない.
なので、retryを繰り返して再送間隔が延びている場合は、次の再送タイミングになるまでキューが溜まり続ける(もしくは、既に溢れている場合は溢れ続ける)
キューを強制的に送信することはできないの?
v0.10.59以前の場合 → リトライ中の場合以外であれば、fluentdのプロセスにSIGUSR1を送ることでキューが吐き出される. リトライ中の場合は、次のリトライタイミングまでは送信されない.全てのキューを吐き出すには、プロセスを停止するしかない.
v0.10.59以降の場合 → リトライ中の場合含め、fluentdのプロセスにSIGUSR1を送ることでキューが吐き出される. (2014/4/4追記: @sonotsさんに頂いたコメントを反映しました)
プロセス停止時の挙動は使用しているバッファプラグインによって異なるが
- buf_memoryの場合
- プロセス停止時に全てのキューが吐き出される.
- buf_fileの場合
- flush_at_shutdownがtrue(デフォルト false)の場合のみ、プロセス停止時に全てのキューが吐き出される.
長くなったのでここまで.