by shigemk2

当面は技術的なことしか書かない

memo Fluentd v0.14 Plugin API Updates #fluentdmeetup

とぴっく

  • なぜAPIを変える必要があったのか
  • 新しいAPIで何が出来るか
  • その後のはなし

たごもりす

新しいプラグインAPI

  • 今までのAPIでは問題があった
  • プラグインAPI関係について体系的なドキュメントがなかった
    • 誰かが書き散らしたブログが参考記事
  • テストコード書きづらい
    • sleep 5みたいなバッドノウハウが蓄積
  • output_plugin
    • 4種類あって分かれていた
    • 考えて作らないといけない
    • 説明がわかりづらい
    • 違いを意識させないようにしたい
  • 設定ファイルを見た時に設定項目の変数が他でも使いまわせるのか分からない→とても不便
  • start/shutdown→なんとなく書かれていたコードが真似されまくってsuperじゃない
  • バッファリングが不便なやり方でしか出来ない
  • バッファはバイト数単位でしか出来ない
    • 100行までならいけるけど101行までならコケるとか
  • Rubyなんで、便利なことをやろうとすると難しい
    • Rubyで出来ることはなんでもやっていいんだ!みたいなサバンナをどうにかしたい
  • コアの設定をプラグインで簡単に上書きしてしまうので面倒
  • FluentdのRubyのコードはダメな例のオンパレードで、Rubyに詳しくない人よりインフラの人が使い始めたので、Rubyのひよコードがどんどん伝搬されていった
  • 自由なRubyのコードが跳梁跋扈していた

便利なようにしていきたい

互換性

  • 説明を、簡単に
  • 0.12 Fluent::Input Fluent::Filter Fluent::Output
  • 0.14 Compatibility layerを利用 Fluent::Compat::Klass -> Fluent::Klass(こういう代入に代表される変換)
    • 0.12→0.14で消失したメソッドとか変数とかを動的に生み出している ので、基本的には動くはず 一部のものは動かない
      • buffer pluginとか。
      • 使っている人が全世界で4人しかいないはずなので
    • 無茶なことをするためにテストコードでごまかしていたプラグインはオミットしてる
    • Engine.emit input_pluginで使われているが、無効、例外へ
      • labelでのルーティングが動かなくなるため(Router.emit)
    • version 0.12
  • 今まで使っていた設定ファイルはどうなるのか
    • ほぼ同じになるようにバージョンアップ
    • ユーザー自身に書き換えてもらうのが理想だけど、プラグインAPI側で自動変更するようにしばらくはAPI側で用意する
  • 0.12 0.14どっちでもいけるpluginは作れないようにした

新しい話

  • 全てのファイルはfleuent/plugin/*.rbで
  • 全てのクラスはFluent::Pluginの下で(いままでは直下でした)
  • サブクラスはFLuent::Plugin::Base
  • いくつかのメソッドについてはsuperを呼び出すように(#configure #start #shutdown)
    • これらのメソッドを呼ぶときにsuperを呼ばないとおかしなことになる(superを強制的に呼ぶ)

構造

  • v0.12
    • Fluent::Input
    • F::Filter
    • F::Output
    • 全部並列
  • v0.14
    • Fluent::Plugin::Baseのうえに、F::P::Inputとか

Fluentd::Plugin::Input

  • ほぼ変わらない
    • overall以外
  • Fluentd的には書きやすくなってる
  • 便利なブロックを組み合わせやすい

Fluentd::Plugin::Filter

  • ここもほぼかわらない
    • filterをかけてrecordかnilをかえす

Fluentd::Plugin::Output

  • けっこういろいろな変更がある
  • 4つのOutputプラグインを統合
    • bufferingの有無に関係なくoutput pluginを使える
  • バッファリングの変更を楽にできる
    • ファイルに書き出す
    • タグごとに分ける
    • などが出来る
    • レコード数指定が出来るようになる(new)
    • timekeyの時間指定が細かくなった(new)
    • レコードに入っているフィールドをチャンク分けできる(new)
    • これらの全部盛り(new)
  • no more forest plugin
  • 今まで4つのプラグインを使い分けないといけなかったのが1つのプラグインに統合

output pluginの実装済みメソッド

  • process
  • write
  • try_write
  • format

  • bufferセクションの有無、プラグイン側のバッファ関係の実装の有無によりAPI側で頑張ってくれる

  • 動的にメソッドを呼び出されて動的に挙動を決定するし、明示的に挙動を決めることも出来る
  • ただし動的な呼び出しは若干動きが複雑
  • 実装が共有できれば、実装済みメソッドを使える

Delayed commit

  • 高レイテンシだとACKがすごく長いので、スレッドがロックされてしまう
    • num threadsの数字を上げてごまかしているが、ACKの長さは変わらない→非同期処理
    • すぐにreturnを返して非同期で処理を行うことで処理を効率化(commit_writeが長く帰ってこなかったらretry)
  • データの一貫性が保持されていない場合がある→定期的にデータをチェックして一貫性が問題なければcommitする
    • 分散ファイルシステムは書いてもすぐに読めないことがある

chunk keys

  • buffer chunk_keysで設定を細かくできる
  • 設定なしだったらチャンクをひとまとめにする
    • flush_interval時にflush / いっぱいになったらflush
  • timekey → この設定の間隔でチャンクを分割(細かく設定するとchunkが分割されすぎるのでwarningにしたいから誰かissueに書いて)
  • ANY_KEYS

configuration flushing buffers

  • flush_mode(lazy interval immediate←レコードが書き込まれた瞬間にflush)
  • flush_interval flush_thread_count
    • 今までと同じ設定
  • delayed_commit_timeout
    • デフォルト60秒
    • コールバックが呼ばれなかったらリトライ

Retry/Secondary

  • Explicit timeout
    • retry_timeout: 72時間
    • retry_max_times: 17回
    • この設定、デフォルト設定を知っている人は少ない
  • retry_type
    • リトライすると間隔が2倍に増える/おなじ間隔でリトライとかを選べる
  • retry_secondary_threshold(percentage)
    • リトライ失敗して諦めたらファイルに書き出すとかっていうのを選べるプラグイン
    • 挙動に不安があるので結構不安だった
    • 今まではsecondaryの書き込みは一発勝負だった
    • 80%って書いてあったら、retry_timeoutが80%以上だったらセカンダリに書き込み始める

Buffer parameters

  • chunk_limit_size
  • buffer_queue_limit バッファがいっぱいになったと見なすもの
  • キューに入っていない書き込み中のチャンクがあり、このチャンクはbuffer_queue_limitに勘定していない
    • ディスク容量ギリギリにしちゃったらディスクが死ぬのでは

Chunk metadata

  • stores various information
    • formattingが自動で行われる
    • いろんな情報が入っている
    • TODOは忘れがち

他のプラグイン

  • primary plugin
    • コアから直接ロードされるプラグイン
  • owned plugin
    • fluentdのコアが直接ロードすることはないけど、primaryに所属して呼び出すプラグイン
    • 例 @type json
      • jsonプラグインを呼ばなくてもprimaryプラグインに所属していてそこから呼び出している
  • storage plugin
    • redisやconsulなどのストレージに接続できる プラグインも作りやすい
  • plugin helpers
    • 好き勝手mixinしていたのをやめた
    • 明示的に宣言してください
    • 新テストドライバ→sleep 3みたいなのが要らなくなる
    • 例: child_process_execute thread_create thread_current_running? timer_execute
    • TBD socket/server for tcp/udp/tls parser formatter
    • helpers: timerって書くと、timer pluginが使えるようになる

New Test Drivers

  • Test Driverが新しくなった
  • Fluent::Test::*TestDriver
  • Fluent::Test::Driver::Input/Output/Filter
    • ログがちゃんと確認できる
    • フォーマットチェック
    • flushのタイミングチェック
      • ここで sleep 5 みたいなのを書かないといけなかったけど不要になった

これからやりたいこと

  • マルチプロセス
    • 課題はまだあるけど
  • forward TLS/認証
  • buffer圧縮
  • プラグインジェネレータ → テンプレがないとひよコードプラグインが群雄割拠しやすい
  • グローバル変数制御
  • プロセス制御
    • 流量制御

書くべきこと

  • 開発者向けガイド(APIのドキュメント)
  • ユーザーガイド(バッファまわりをより詳細に)