flunetd、forward先がダメだった時にforward元である程度ログを担保したい
April 1, 2014
fluentdのbufferとforwardについて調べたのでメモ。
fluentd v0.10.45
追記( 04/02 00:27)
@kenjiskywalker flushしようとしてできなかったbufferにもlimitまで溜まるから、1kbのbufferが128個で限界にはならないような気がしますが
— fujiwara (@fujiwara) April 1, 2014
@fujiwara 今手元で試したんですけどflush_interval関係なさそうですね。普通にflush_interval 1s buffer_chunk_limit 10とか指定してもそれ以上のbuffer保持してました
— kenjiskywalker (@kenjiskywalker) April 1, 2014
@tagomoris @fujiwara なるほど〜!
— ブラッド・ピット (@kenjiskywalker) April 1, 2014
とのことです。
こちらも参照してください。
fluentd の buffer あふれ改善議論 - togetter
flush_interval
はあくまでflushするだけであって
貯まる分は
buffer_chunk_limit x buffer_queue_limit
が影響する。ということですね。
update( 04/02 11:40 )
参考
fluentd - Buffer Plugin Overview
tagomorisのメモ置き場 - FluentdでバッファつきOutputPluginを使うときのデフォルト値
構成
- 各ホストから集約サーバへ
foward
している - 集約サーバはログを受け取ってゴニョゴニョしている
Buffer
BasicBuffer
FileBuffer
MemoryBuffer
buffer_chunk_limit
FileBuffer = デフォルト(8MB)
MemoryBuffer = デフォルト(8MB)
buffer_queue_limit
FileBuffer = デフォルト(256)
MemoryBuffer = 64
総バッファサイズ
FileBuffer
= 8 * 256 = 2048(2GB)MemoryBuffer
= 8 * 64 = 512(512MB)
flush_interval
flush_interval = デフォルト(60s)
Bufferされる値を算出する
fluentd - Buffer Plugin Overview
When the top chunk exceeds the specified size or time limit
(buffer_chunk_limit and flush_interval, respectively),
a new empty chunk is pushed to the top of the queue.
The bottom chunk is written out immediately when new chunk is pushed.
例えば
<match **>
type forward
flush_interval 1s
buffer_queue_limit 128
buffer_chunk_limit 1g
<server>
host localhost
port 24225
</server>
</match>
と設定していた場合、buffer_queue_limit 1G
とflush_interval 1s
の
どちらかの閾値を超えた場合にflushされます。
If the bottom chunk write out fails,
it will remain in the queue and Fluentd will
retry after waiting several seconds (retry_wait).
If the retry count exceeds the specified limit (retry_limit),
the chunk is trashed. The retry wait time doubles each time
(1.0sec, 2.0sec, 4.0sec, …).
If the queue length exceeds the specified limit (buffer_queue_limit),
new events are rejected.
例えば上記設定例で
forward
先にデータが転送できなかった- ログファイルは
1kB/sec
の書き込み
である場合、buffer_chunk_limit 1g
に達する前にflush_interval 1s
に引っかかり
flush_interval 1s
x buffer_queue_limit 128
(128kB)分のバッファを確保した後
新しいqueueは受け付けられなくなるかと思いきや、flushはあくまでflushなので
バッファする量は
- buffer_chunk_limit x buffer_queue_limit
で決まるとのこと。
forward時にログの転送元でどれだけのバッファを担保したいかは
ログの流量と転送元と転送先のスペックによって変わるので
みんなよしなにやっているのではないかと思います。
forward
結論から先に書いておくと
<match **>
type forward
hard_timeout 180s
phi_threshold 100
<server>
host a
port 24224
</server>
<server>
host un
port 24224
standby
</server>
<secondary>
type file
path /var/log/fluent/forward-failed
</secondary>
</match>
上記のような冗長構成にできるのは、forward先が
いずれのサーバであっても同様の処理が行える時に限る。
ということです。
例えばa
に障害があってhard_timeout
で設定している
180秒を超えた場合、転送先がun
に変わります。
しかし、結局a
で処理していたログとun
に流れたログを
どこかでmergeしたりする必要があるのであれば、
冗長構成を設定しない方が運用は楽かと。
デフォルトの設定であれば
となっており、最大131072 sec
リトライしてくれます。
ログの流量によってはその前に
buffer_chunk_limit
xbuffer_queue_limit
上記の閾値に引っかかる可能性がありますが、
閾値に引っかかる前にa
のサーバの状態を復活させた方が
オペレーション的には楽だと思います。
絶対ロストしてはいけないデータだから冗長構成は必須!!!
という場合はそもそもfluentdの冗長構成の前にやることがあると思います。
というようなことを書いたのですが、認識に誤りなどあれば
ご指摘頂ければ幸いです。