fluent-plugin-http-ex をリリースしました!
Fluentd in_http プラグインにデータを送る際、ある程度データをまとめて送ったり、in_forward のように高速に処理させたかったので in_http にいくつか機能を追加した in_http_ex をリリースしました!!
- github
https://github.com/hiro-su/fluent-plugin-http-ex
- rubugems
https://rubygems.org/gems/fluent-plugin-http-ex
in_httpからの変更点
1. 受信フォーマットに list と chunked の追加
受信フォーマットに list と chunked を追加。
- JSON list の場合
'[{"action":"login","user":2},{"action":"login","user":2}]'
- MessagePack list の場合
record = {"action" => "login", "user" => 2} [record,record].to_msgpack
- chunked の場合
HTTP1.1の Transfer-Encoding: chunked でデータを受取ります。chunkedはMessagePack形式の物だけを想定しています。以下、リクエストヘッダ部分だけを抜粋。
POST /ms/test.tag HTTP/1.1 Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3 Accept: */* User-Agent: Ruby Content-Type: application/x-msgpack Transfer-Encoding: chunked Connection: Keep-Alive Host: localhost:8888
2. content-typeの追加
Content-Type ヘッダフィールドに application/x-msgpack を追加しました。msgpack形式時は application/x-www-form-urlencoded よりBodyにパラメータを付けない分、速度面で多少有利な気がします。
3. tagの前にresourceを追加
resourceにより受けるフォーマットを分離。
- resource無し
in_httpと同じ形式です。
http://localhost:8888/tag.here
- json
jが1レコードのjsonでjsがlistを受けます。
http://localhost:8888/j/tag.here http://localhost:8888/js/tag.here
- msgpack
mが1レコードのMessagePackでmsがlist, chunkedを受けます。
http://localhost:8888/m/tag.here http://localhost:8888/ms/tag.here
4. keepalive_timeout
keepalive_timeout 0sでコネクションが切れないように変更
簡単な使い方
例えば、JSON list形式
$ curl -X POST -H 'Content-Type: application/json' -d '[{"action":"login","user":2},{"action":"login","user":2}]' \ http://localhost:8888/js/test.tag.here;
Fluentd側では以下のように受信します。
2013-08-07 19:42:22 +0900 test.tag.here: {"action":"login","user":2} 2013-08-07 19:42:22 +0900 test.tag.here: {"action":"login","user":2}
パフォーマンス
簡単にですが、それぞれのフォーマットの速度比較をしてみました。
in_http と in_http_ex に対して 10,000 record を送ります。
使用したコードはexamples以下に起きました。
https://github.com/hiro-su/fluent-plugin-http-ex/tree/master/examples
- マシンスペック
Mac OS X 10.8.2 1.8 GHz Intel Core i5 8 GB 1600 MHz DDR3
コンフィグ
<source> type http port 7777 bind 0.0.0.0 </source> <source> type http_ex port 8888 bind 0.0.0.0 body_size_limit 300M keepalive_timeout 0s </source> <match **> type stdout </match>
結果
in_http: json
$ time ruby examples/json.rb real 2m27.480s user 0m7.252s sys 0m4.438s
in_http: msgpack
$ time ruby examples/msgpack.rb real 2m36.408s user 0m8.249s sys 0m4.441s
in_http_ex: json
$ time ruby examples/json.rb real 2m30.639s user 0m7.195s sys 0m4.686s
in_http_ex: msgpack
$ time ruby examples/msgpack.rb real 2m28.442s user 0m7.126s sys 0m4.324s
in_http_ex: json list
$ time ruby examples/json_list.rb real 0m18.179s user 0m0.872s sys 0m0.477s
in_http_ex: msgpack list
$ time ruby examples/msgpack_list.rb real 0m13.787s user 0m0.908s sys 0m0.470s
in_http_ex: chunked
$ time ruby examples/nc_chunked.rb real 0m1.584s user 0m0.244s sys 0m0.107s
さいごに
簡単なパフォーマンス測定でしたが、 json < msgpack < json list < mgpack list < msgpack chunked のような結果になりました。msgpackのchunked形式がやはり速かったです。バッチ処理的に1日分のファイル内容をFluentdに対して送信したりする時に良さそうです。
ただ、個人的に一番取り扱いが良さそうなのは、json listとmsgpack listだと思っています。
また、バグや改善点など有りましたらどんどん pull req して頂ければと思います!