2022年1月6日にFluentdの最新版となるv1.14.4をリリースしました。これが2022年を迎えて最初のリリースになります。
このブログ記事では、v1.14.4のリリースのポイントについて、Fluentdのメンテナの観点から解説を加えようと思います。 開発された機能項目だけではなく、その背景と経緯についても説明を加えますので、 これを読めばFluentdの最新の開発動向がつかめるはずです。
Fluentd v1.14.4の最新動向
(1)データの分割格納ロジックの改良
今回のリリースの目玉は、巨大なデータの格納処理の改善です。
まず、内部の話になりますが、Fluentdはログファイル等から読み取ったデータをチャンクというかたまりに分けて保存します。 チャンクとは、データを詰め込む仮想的な入れ物で、「最大1MBまで」といった容量があり、満杯になるごとに転送先に送られます。
言葉の説明だけだとわかりにくいので、大雑把な概念図を示します。
この仕組みで難しいのは容量の管理です。Fluentdが受け取るデータのサイズはあらかじめ予想ができないので、 しばしば残りの容量を超えてしまうような大きなデータを受け取るといったことが起きます。 このような場合でも、Fluentdはなんとかやりくりしてチャンクに収める工夫をします。
- まずは既存のチャンクに入れてみて、容量があふれるか見てみる。
- 容量があふれるようであれば、データを10分割して少しずつ格納していく。入らない場合は再帰的に分割を繰り返す。
- どうしても入り切らない場合(例えば一つのメッセージだけでチャンクの容量を超えてしまう場合)、
BufferChunkOverflowError
を出力してデータを捨てる。
v1.14.4以前のバージョンでは、このロジックに足りない部分があり、 上手く分割すれば格納できる場合にまでデータを捨ててしまう場合がありました。
今回のリリースでは、この分割格納ロジックに手を入れて、分割格納できる場合はきちんと格納できるようにしました。
これにより、巨大なメッセージの束が渡された場合でも、BufferChunkOverflowError
によるデータロスが起きにくくなってします。
(2)データの読み込み制限の新設
前節の議論を別の視点から捉えると、そもそもチャンクの容量に格納できないようなエントリは、 読み取る時にチェックで弾くべきではないかという発想が出てきます。 例えば、チャンクの容量が8MBとすると、一行で100MBを超えるような巨大なエントリはどだい読み取るだけ無駄です。
Fluentd v1.14.4ではこのアプローチでの対策もサポートしました。
具体的にはmax_line_size
というオプションをin_tail
プラグインに新たに設け、
一定のサイズを超えるようなエントリは読み飛ばせるようになっています。
このオプションは具体的には次のように使うことができます:
<source>
@type tail
path /var/log/nginx/*.log
...
max_line_size 8MB # skip very long lines
...
</source>
(3)macOSでの追記書込バグの回避
Ruby 2.7/3.0のIO実装にはバグがあり、ストリームのコピー時に追記した部分を切り詰めてしまうという既知の不具合があります
(詳細はRuby#18388を参照ください)。
この影響で、以前のバージョンでは、macOSのみout_file
プラグインのappendオプションが上手く動かないという不具合がありました。
今回のリリースでは、macOSでRuby 2.7/3.0を利用している環境向けにIO.copy_stream()
に依存しないフォールバック用のロジックを追加しました。
この対策により、macOSでもファイルへの追記書き込みが正しく動くようになっています。
まとめ
今回の記事では、Fluentd v1.14.4について最新情報をお届けしました。 最新版を使ってみて、何か気になる点があればぜひGitHubで開発チームまでフィードバックをお寄せください!