無印吉澤

Site Reliability Engineering(SRE)、ソフトウェア開発、クラウドコンピューティングなどについて、吉澤が調べたり試したことを書いていくブログです。

Fluentd Meetup 2016 Summer レポート 〜 v0.14 の新機能からプラグイン開発者向け API まで

f:id:muziyoshiz:20160602000413p:plain
  • イベント名:Fluentd Meetup 2016 Summer
  • 開催日時:2016-06-01(月)
  • 会場:イベント&コミュニティスペース dots.

約1年ぶりに開催された Fluentd Meetup に参加してきました。今回は、5月31日にリリースされたメジャーバージョンアップの v0.14 について、ユーザ向けの機能紹介から、プラグイン開発者向けの深い話まで、盛りだくさんの内容でした。自分でプラグインを書くくらい、Fluentd をヘビーに使う人向けのイベントという感じで、どの話も面白かったです。

最近、私は Fluentd を使う機会が全然なかったこともあって、「Fluentd も機能的には枯れてきて、そろそろ新機能もあまりないだろう」と思っていたのですが、まだこんなに改善の余地があったのか……とちょっと驚きました。個人的には、古橋さんの講演で将来の構想として出てきた、Kafka っぽい PubSub は便利そうなので是非実装してほしいです。

以下、講演内容のメモです。プレゼンに書かれてなくて口頭で説明されていたことや、個人的に気になったことを中心にメモしています。

講演内容

Past & Future of Fluentd (古橋 貞之, @frsyuki)

  • Fluentdの歴史

    • 2011年6月に最初のバージョンをリリースした。今年の6月で5年。ここまで続くと、かなり成功したOSSと言っていいのではないか。
    • 新メジャーバージョンの 0.14 が昨日リリースされた。
  • 2年前にリリースされたv0.12の機能の振り返り

    • タグの書き換えを不要にする label と filter
  • 将来の構想

    • Advanced back pressure - 転送先が詰まるのを防ぐ
    • PubSub & pull forward - Kafkaに近い発想。ログが必要なアプリが取りに行く
    • Compressed buffer
    • Distributed buffer - twitterがリリースした distributedlog や、Apache BookKeeper のような機能を Fluentd の buffer のところに入れる
    • Service plugins - パッケージ化されたソフト(例えば Norikra)をFluentdで動作させるようにする。service label を書くだけで起動。インストールが簡単になる
    • Schema-validated logging - バリデートされたログだけを転送することで、無駄な転送や、データベース書き込み時のエラーを回避する
    • Centralized config manager - Chef や Ansible を使うことも考えられるが、Dockerで起動したインスタンスのなかの設定に Chef などを使いたくない。これに fluentd-ui が組み合わさると嬉しい
  • Fluentdのロゴが変わる予定

v0.14 Overview (中川 真宏, @repeatedly)

  • New Plugin APIs

    • v0.12向けに作ったプラグインは、互換性レイヤがあるので、ほぼ動くはず
    • インスタンス変数に直接アクセスしているようなプラグインは、動かない可能性がある
    • 次の v1 でも互換性レイヤは残す予定
  • buffer の設計の大幅な見直し

    • v0.12 buffer design: chunkの保存方法。ElasticSearch に書き込むときに、インデックスの値を見て書き込み先を変える、といった場合に問題になった。リトライがうまくいかない。
    • v0.14で、chunkの管理が柔軟になり、このような問題は解決できる
  • Plugin Storage & Helpers

    • プラグイン内で使えるストレージレイヤ(KVS)の導入
    • プラグインの作成時によく使う雛形コードをhelperで提供
  • Time with nanosecond

    • ミリ秒とナノ秒のどちらにするか、という議論があったが、ナノ秒でログを出すシステムが増えてきたのでナノ秒
    • 内部的には Fluent::EventTime という形で持つ。既存のプラグインに対しては Integer っぽく振る舞うクラス。
  • ServerEngine based Supervisor

    • プロセスモデルを ServerEngine に置き換える
  • Windows support

    • Linux 向けに特化したコードを、Windows で動くように直したりした
    • HTTP RPC でバッファのフラッシュなどを行う
  • v0.14.x - v1

    • https://github.com/fluent/fluentd/issues/1000 に並んでいる
    • v1 を出す。v1 で新機能を入れることはない。v1 は今まで入れたAPIをFixする、と宣言するためのバージョン。フィードバックは v0.14 のうちにしてほしい
    • v1 は 2016 4Q か 2017 1Q に出る
    • いくつか v1 で消したい機能はある
  • v0.14 系でこれから入れる予定の目玉機能

    • Symmetric multi-core processing: パフォーマンス向上。TCPポートをWorker間で共用し、Workerで処理を分ける。ServerEngine を使って実現する
    • Counter API: Workerが分かれるので、カウンタを作りづらくなる点をカバー
    • secure-forward をコアに入れる。forward と secure-forward の細かい違いをなくす
  • ベンチマーク結果

    • CPU使用率が、v0.14 で若干上がっている
    • EC2で、100,000msgs/sec での測定結果によると、CPU使用率が4〜5%上がった
    • v0.14はリリースしたばかりで、性能改善できる余地が残っている。これから改善する予定
  • td-agent 3

    • fluentd v0.14 は td-agent 3 から採用(現行の td-agent 2 系には入らない)
    • Ruby 2.3 に上げる
    • Windows 向けパッケージも提供予定
    • リリース日は未定(v0.14 がまだ stable と言えないので)
  • Q) chunk から取得したログの一部で処理が失敗した場合、リトライしたいと思うが、その場合 chunk の詰め直しはできるか?

    • A) できない。その場合は、エラーストリームという機能を使ってほしい

Fluentd ServerEngine Integration & Windows Support (成田 律太, @naritta)

  • 自己紹介

    • 2015年の Treasure Data のインターンシップに参加し、今年入社した
  • ServerEngine

    • Unicorn と大体同じようなもの
    • Supervisor, server, worker の構成を簡単に作れるようにするためのフレームワーク
    • Worker Module, Server Module を Ruby で書く
    • Worker type: thread, process, spawn
    • v0.14 では spawn worker type を利用している。Windows に fork の機能がないため
  • Fluentd で ServerEngine を採用したことによるメリット

    • auto restart
      • Linux でも Windows でも、fluentd のプロセス(worker)をKILLすると、自動的にリスタートするのを確認できる
    • live restart
      • 設定変更したあとでシグナル(または HTTP RPC)を送ると、worker だけをリスタートできる
      • server が TCP 接続を持っているので、ログは欠損しない
    • socket manager
      • server 側で listen して、socket を worker に共有する
      • 将来的にはマルチコアでソケットを共有するために ServerEngine を使う(いまはマルチコアで動かすには in_multiprocess plugin を使う必要がある)
    • signal handler
      • signal handler と log rotation は、Fluentd ユーザにとってのメリットというより、内部実装に関するメリット
      • シグナルをキューに溜めて、シグナル同士の競合を防ぐ
    • log rotation
      • ruby core にすでにポーティングされている機能
      • マルチプロセスでのログローテーションなど
  • Q) ServerEngine が入ることで、設定ファイルが増える?

    • A) Fluentd が内部的に ServerEngine の設定ファイルを作って、ServerEngine に渡す。ユーザ側は Fluentd/td-agent の設定ファイルだけを編集すれば良い

Fluentd v0.14 Plugin API Updates (田籠 聡, @tagomoris)

  • 何故新しい API セットを作ったか?

    • いままでのプラグインには、開発者向けドキュメントがなかった。みんな他の人の書いたプラグインの真似をして書いている
    • プラグイン内で独自にスレッドを起動するようなことが必要で、そのせいでテストしづらい
    • あるプラグインで使えるパラメータが、他のプラグインでも使えるのかどうかがわかりづらい
    • 割りとコアな処理をプラグイン側で上書きしてしまっていることがよくある
    • などなど
    • 上記のような問題を解決したい。また、便利な機能も一緒に提供することで、移行を進めたい
  • Compatibility of plugins

    • v0.12のプラグインは Fluent::Input などのクラスのサブクラス
    • compatibility layer: Fluent::Compat::Klass で、v0.12 にしかないメソッドを提供するなどして、互換性を維持
  • Compatibility of configurations

    • v0.12 形式のパラメータを v0.14 形式に自動変換する helper を提供する。plugin 開発者にこれを使ってもらう必要がある
    • v0.14 API を使ったプラグインを、v0.12 で動かすことはできない(ようにした)。gemspec に依存関係を書いてもらう必要がある
  • v0.14 プラグインクラスの書き方

    • すべてのクラスを Fluent::Plugin モジュールの下に置く(いままでは Fluent 直下だった)
    • 親クラスのメソッド(#configure とか)をオーバライドするときは必ず super を呼ぶ
    • super を呼んでない場合は、互換性レイヤが代わりに super を呼んで、WARNING を出す
    • 親クラス(Fluent::Plugin::Input とか)の階層を整理
  • Fluent::Plugin::Output

    • Output Plugin は物凄くいろいろ変わった。v0.12 まではやりたいことによって異なるクラスを使い分ける必要があったが、1個の Output クラスに統合された
    • chunk を分ける条件を細かく指定できるようになった。いままではサイズのみの chunking だったが、例えば時間でも chunking できるし、時間とサイズの組合せでもできる
    • Non-buffered, buffered synchronous, buffered asynchronous のいずれか1個を実装してあれば動く
  • Delayed commit

    • 書き込みの ACK を待ちたい場合、いままでは write メソッドの中で待つ必要があった。write メソッドが終わると、送ったデータが chunk から消されてしまうため
    • v0.14 では try_write メソッドで commit を待たずに return する。この時点では chunk が消されない。非同期のチェックスレッドが ACK を受け取って #commit_write が呼ばれた時点で、chunk が消される
    • ユースケース:分散ファイルシステムに書き込んでから、正しく読めることを確認してから chunk を消したい場合
  • configurations: flushing buffers

    • chunk を flush するタイミングを、細かく制御できるようになった
    • flush_mode: immediate → すぐに書き込んで欲しいが、失敗した時はリトライして欲しい場合に使うモード
  • Retries

    • いままではリトライ回数(retry_count)しか指定できなかったが、タイムアウト(retry_timeout)を指定できるようになった(どれだけの期間、リトライし続けるか)
    • いままでは72時間リトライし続けていた。この仕様は自明ではなかった。いつまで待てば諦めが付くのか、誰にもわからない状態だった
  • その他のプラグイン: Buffer, Parser, Formatter, Storage, ...

    • これらを v0.14 では "Owned" plugin と呼ぶ → 他のプラグイン経由で実体化されるプラグイン
      • 対義語は primary plugins → Input, Output, Filter plugin
    • Storage plugin:プラグイン内でデータを永続化したい場合に使うプラグイン
      • 例:file plugin の pos file で管理している情報を、storage plugin で永続化
  • Plugin Helpers

    • ヘルパーを使いたいときは、明示的に "helpers :name" と指定してもらうことで、どのヘルパーを使っているのか明示されるようにした
  • New Test Drivers

    • いままでは実行タイミングに依存していたようなコードを、きちんとテストできるようにした
    • 例えば、flushのタイミングを制御するとか
  • Plans for v0.14.x

    • 古橋さんの話+α
    • plugin generator を入れようと思っている。いまは、他の人の書いたプラグインの真似をしてプラグインを書く、という状態で、これは良くない
    • 新しいAPI:Fluentd 全体で使えるバッファサイズの上限を指定、Counter API
  • 開発者向けのドキュメントはこれから書く(書かなければいけないと思ってはいる)