fluentdのメモリが爆発していろいろ調べたので、そのメモを残しておく
本番環境でのfluentdメモリの使用量とメモリ使用量を抑制するための設定
ざっくりまとめると
- chunk_limit_size は可能な限り小さく
- flush_at_shutdown を true してる場合は、受信側が処理できるぐらい大きさに total_limit_size を設定する
fluentd でのメモリの関係
送信用と受信用のインスタンスを1つずつ計2つ使って、fluentdでログを送信するような構成を組んで主に受信側のメモリについてのことを書いていく
fluentd では chunk_file という単位でデータを送信してる。その chunk_file を貯めておくバケツのことを buffer と読んでいる
fluentd は受信したデータを buffer に書き出すまで、メモリ上に保持する。そのため、1 つの chunk_file のサイズが大きいと、メモリを相応に使用するようになる
chunk_limit_size を設定しない場合デフォルトで 512MB になっており、さらに compress オプションをつけると、512MB に圧縮された chunk_file が受信側が処理する必要が出てくる
GCP の e2-standard-8 のインスタンスで、chunk_limit_size を段階的に変更して、メモリの使用量を確認したのが以下の表になる
chunk_size | メモリ使用量 |
---|---|
512MB | 2G |
60MB | 1.2G |
24MB | 500MB |
12MB | 300MB |
6MB | 200MB |
2MB | 190MB |
印象としては、chunk_fileの大きさが100MB以上になってくると、受信サーバのレスポンスが極端に悪くなり、最悪はno responseエラーが出ることもある
その状況なってしまうと、送信側にretry_forever オプションをつけている場合、レスポンスがないために再送し続けて、さらに受信側に負荷がかかるようなことが現象として起きていた
その辺考えると、特にfluentdでニアリアルタイム性が求められる場合は、chunk_limit_size を可能な限り小さくして、送信流量を調整することが必要となる
設定の例
- flush_interval、flush_thread_countは適宜調整する
- bufferはデータを一時的に貯めておく場所なので、total_limit_size は極力小さい方がいい
- flush_at_shutdownをtrueにする場合、再起動時に最大でtotal_limit_size分のデータを受信側に投げつけるので、これも小さい方がよい
- compress gzipをしている場合、1つのchunkfile(2MB)で10MB程度送信できるので、テキストのログを送信するだけの用途なら1~2MBのサイズでほぼほぼ問題ないはず
- 送信側でbufferがいっぱいになったとしても、fluentdはログの読み込みをやめるだけで、ログが送信できなくなっている事態以外の問題は起きない
#あくまで参考程度
@type forward
compress gzip
keepalive true
keepalive_timeout 300s
require_ack_response true
expire_dns_cache 60
<buffer>
@type file
path PATH_TO_BUFFER
chunk_limit_size 2MB
total_limit_size 40MB
flush_mode interval
flush_interval 5s
flush_at_shutdown true
flush_thread_count 1
retry_forever true
retry_max_interval 5m
</buffer>
fluentdでメモリを抑えるための設定まとめ
- chunk_limit_size は可能な限り小さく
- flush_at_shutdown を true してる場合は、受信側が処理できるぐらい大きさに total_limit_size を設定する