読者です 読者をやめる 読者になる 読者になる

おくみん公式ブログ

おくみん公式ブログ

Influent ベンチマーク - Part 1 #fluentd

Fluentd

f:id:okumin:20170124002659p:plain

Java 版 Fluentd サーバである、Influent のベンチマークを取ってみました。今回は第一弾で、今後も性能を改善しながら、都度ベンチマーク結果を載せていく予定です。

テスト概要

fluentd-benchmark を用いて Fluentd 及び Influent へ負荷をかけます。これは dummer で生成したイベントを Fluentd エージェントで大量に送りつけるもので、fluent organization のものをほぼそのまま用いています。

受信サーバの処理は、受信したイベントの数を1秒ごとに標準出力に書き出すという単純なものです。Fluentd のテストには上記の fluentd-benchmark に同梱されている設定を用います。Influent のテストには同じような処理を行うこちらのアプリケーションを用います。

Disclaimer

Fluentd と Influent の比較について

この記事は Fluentd のベンチマーク結果を Influent のベンチマーク結果に併記しています。ただし、この結果をもとにどちらの性能が優れているかを推し量ることはできない、という点に留意してください。

Influent は Fluentd が持つ機能のいくつか、例えばルーティング機能のようなものを提供していません。そのため、直接比較すると Fluentd に不利な結果となるでしょう。また次に述べるように Fluentd の性能を引き出しきれている保証もありません。

Fluentd のベンチマーク結果について

本記事に記載している Fluentd のベンチマーク結果は、本来の性能を発揮できていない可能性があります。理由は、私が Fluentd や Ruby のパフォーマンスを引き出す術に明るくないからです。

サーバのセットアップ方法やベンチマークの実行方法は influent-benchmark により管理されているので、よりよいテスト方法をご存じの方は PR してくれると嬉しいです。

テスト環境

サーバ

送信サーバ及び受信サーバには、Google Compute Engine asia-northeast1 リージョンの n1-highcpu-32 を用いました。

送信サーバ一台だと負荷をかけきれないケースがあるので、送信側は二台用意しました。それぞれ20プロセスの Fluentd が並列にイベントを送信します。

バージョン

環境構築は influent-benchmark の 78828a54a18783f5b976935e3df33aa709164a6d で行いました。

Fluentd のバージョンは 0.12.31 で、Influent のコミット ID は f38aa35ca708a72df66f07b5e87a43a0b24eb3ef です。

プロトコル

Fluentd 0.12 を用いて、at-most-once(require_ack_response なし)プロトコルでイベントを送信しました。at-least-once でも軽く試しましたが、Fluentd がそれなりの数のイベントをバッファリングしつつ送っているからか、あまり結果は変わりませんでした。

テスト結果

ある程度負荷をかけて安定したタイミングで、受信していたイベント数をアバウトに記録しました。また今回は CPU がボトルネックとなっていたので、CPU 使用率も載せています。

Influent のアプリケーションのうち、すごくアクティブなスレッドは1スレッドのみです。CPU 使用率が100%を超えている分はほぼ GC スレッドによる処理であると思われます。

Fluentd Influent
送信イベント数(秒) 受信イベント数(秒) CPU (%) 受信イベント数(秒) CPU (%) 備考
400000 400000 40~45% 400000 30~45%
600000 600000 60~65% 600000 40~55%
800000 800000 80~90% 800000 60~70%
1000000 800000~1000000 100% 1000000 70~90%
1200000 800000~950000 100% 1200000 85~100%
1400000 N/A N/A 1400000 100~115%
1600000 N/A N/A 1600000 125~145%
1800000 N/A N/A 1800000 95~155% テスト中に JVM のヒープサイズ拡張
2000000 N/A N/A 2000000 100~115%
2200000 N/A N/A 2000000~2150000 110~115%
2400000 N/A N/A 2000000~2150000 110~115%

雑感

Java で Fluentd の in_forward っぽいことをするライブラリを作りました』で予想していたとおり、シンプルな処理では大きな差が出ませんでした。プロファイリング結果によると、PackedForward の MessagePackEventStream をパーズする処理でかなりの CPU を使ってしまっているので、性能が劇的に改善することもなさそうな感じがしています。

とはいえ Influent は性能面の最適化をほとんどしていないので、後述する TODO を解決して、またベンチマークを取っていこうと思います。

TODO

MessagePack デコード処理の改善

msgpack-java はインクリメンタルなデコードができないので、パケットを受け取る度に毎回一から unpack しています。この部分がそこそこプロファイリング結果に出てきていたので、ストリームデシリアライザを実装しようと思っています。

マルチスレッド対応

現状 Influent のネットワーク処理〜MessagePack のデコード処理部分はシングルスレッドで動いています。一方ユーザーの処理(受け取ったイベントをどこかに送信するとか)はマルチスレッドで処理できるようになっています。この構成だと 10Gbps の線の上で、Influent がボトルネックとなってしまうことがほぼ確定しています。

次のバージョンの Fluentd にはポートを複数ワーカーで共有する機能(Symmetric multi process)が入るらしいので、Influent にも MessagePack のデコードをスケールする仕組みを導入したいです。

0.14 を使ったテスト

現在リリースされている Fluentd 0.14 はタグの送信フォーマットが仕様に沿っておらず、Influent で受け取れないので今回は 0.12 のみを使ったテストとなりました。Fluentd 0.14 自体の性能にも関心があるので、特に Symmetric multi process 機能が入ったらまた比較してみたいです。

より現実的なテストケース作成

Fluentd 本体がよくできている以上、Java の性能を活かせるのは、やはり重い計算を行う場合や、マルチスレッド処理、IO を伴う処理が必要な場合ではないかと考えています。fluentd-benchmark は若干シンプルよりなので、Google Cloud Pub/Sub に書き込むとか、そういうケースも試験できたらいいなと考えています。

関連リンク

okumin.com が GCP 上で不死鳥のように蘇りました #GCP

GCP Docker

f:id:okumin:20161204200212p:plain

壊れて動かなくなっていたおくみん公式サイト(okumin.com)を復活させました。

新しい okumin.com はただの静的サイトですが、裏では色々と新しいことに挑戦しています。

チャレンジ

GCP

okumin.comGoogle Cloud Platform 上で動いています。

これまで自分は主に VPS を用いてホムペ作りをしていました。 そろそろクラウドをガッツリ使っていきたい気持ちになったので、最近東京リージョンが出たばかりの GCP を使ってみることに。

後述する GKE のように、GCP には魅力的なマネージド・サービスがたくさんあって日々便利さを感じています。

Docker

流行りの Docker を導入してみました。

以前『Docker実践ガイド』を読んだときは、よさはあるがネットワーク設定を管理してくれるシステムがないと実運用は難しそうだなという印象を受けました。

その点 GCP には Kubernetes のマネージド・サービスである Google Container Engine(GKE) があるので、なんとかなるかなと思いつつ利用してみると、これがありえんくらい使いやすかったです。

GCP、Kubernetes、Docker と登場人物が多いので最初は少し戸惑ったものの、一度使い方を覚えてしまえば手軽にコンテナのデプロイができるようになりました。 その上 Kubernetes にはローリングアップデート機能や、コンテナの死活監視及び再起動を自動で行ってくれる機能があり、運用が非常に楽になります。 コンテナからの標準出力を自動的に Stackdriver Logging に集約し、さらにそれを BigQueryGoogle Cloud Storage へ継続的にエクスポートすることも可能です。

これまで Docker の主なメリットは性能やポータビリティであると思っていました。 今ではむしろ、各種プロセスがコンテナという共通の仕組みに乗っかることで、さまざまな効率化・自動化が実現できることこそ Docker の真価であると感じています。

HTTPS

これまた流行りの Let’s Encrypt を用いて HTTPS 対応しました。 これからのインターネッツはすべて HTTPS であってほしいです。

まとめ

復活した okumin.com の裏側についてまとめました。

今後は全サーバを GCP 上に設置したいと思うくらい、GCP によさを感じました。 無料トライアルでもらった300ドル分のクレジットがなかなか減らないので、データベースやビッグデータ系のマネージド・サービスなんかも試していきたいです。

Influent が Fluentd Related Projects の仲間になりました

Fluentd

f:id:okumin:20161119193057p:plain Related Projects | Fluentd

先日公開した Influent を、http://www.fluentd.org/Related Projects に載せていただきました。

経緯

Qiita へ投稿した『Java で Fluentd の in_forward っぽいことをするライブラリを作りました』が @repeatedly さんの目に触れて、それっぽい反応をなさっていたのでぜひぜひとお願いしました。

今後の抱負

できたばかりでまだ安定しているとはいえないライブラリですが、頑張ってメンテしていきたいと思います。

ビッグデータ界隈は JVM 言語が広く使われているので、そのあたりで使えないか模索しています。 とりあえず Spark Streaming の Fluentd Receiver を実装してみる予定です。

関連リンク

C++ で Apache Kafka を実装してみた

C++ Kafka

C++11/14 コア言語』を読んで C++ に惹かれ、使ってみたくなったので、Apache Kafka を実装してみました。

作ったもの

Cafca

C++ を書くならせっかくだしミドルウェアを作ってみよう、というわけで比較的構造がシンプルな Apache Kafka を移植しました。

とはいっても習作であり、プロダクトとして利用できるレベルではないです。 Produce API, Fetch API あたりしか実装していません。 分散周りが未実装で、無数のバグがあり、かつパフォーマンスも出ないであろうという状態です。

C++ 感想

C++ は想像していたより先進的な機能が多く、自分のようなモダンプログラマでも楽しめる言語でした。 テンプレートやラムダ式を駆使すれば表現力に定評のある Scala に負けないくらい、パワフルな記述が可能です。

例えばテンプレート特殊化を使えば型クラスっぽい多相を実現できます。ネットワーク IO ライブラリ Boost.Asio はラムダを使ってハイレベルで使いやすい抽象化に成功していると感じました。

今後

Kafka のソースコードを読んで、データ構造、ディスク IO 周りをアーキテクチャレベルで見直せばよくなる余地があると直感しています。

なので暇があればその辺を作り直して、API も揃えて、本物の Kafka とベンチマーク結果を比較したいという気持ちが若干あります。 そこまで行くと Kafka とはかなり違ったものになるので、一から新しいものを作ることになるかもしれませんが……

ScalaMatsuri 2016 で LT してきました #ScalaMatsuri

Scala

人がたくさんいてとても緊張しました。

関連リンク