こんにちは。ヤフー株式会社 システム統括本部の望月です。
私たちは先日、高速ファイル/メッセージ転送システムの K2HFTFUSE(ケーツーエッチ、エフティーフューズ) を公開し、この場でも紹介させていただきました。(高速ファイル/メッセージ転送 K2HFTFUSE の紹介)
前回の Tech Blog では機能やプログラムの起動方法などを説明しましたが、今回はもっと詳細なパフォーマンス測定をしてみました。
皆さんは複数台のサーバー構成でデータを収集したり、メッセージ通信が必要なときに、どんなシステムをお使いでしょうか。
fluentd や kafka を利用されている方も多いのではないでしょうか。
今回は同じ条件で fluentd と kafka とも比較してみましたので既にこれらのプロダクトをお使いの方にもご一読いただければ幸いです。
目次
K2HFTFUSE とは
パフォーマンス測定結果
- パフォーマンス結果(ボトルネックとなる環境なし)
- 1Gbps ネットワークでの測定(ネットワークのボトルネック環境)
- HDD 使用環境での測定(ファイル・デバイスのボトルネック環境)
他プロダクトとの比較測定結果
まとめ
- K2HFTFUSE の性能について
- 各プロダクトとの比較
- 各プロダクトの設定作業について
- ログ収集ツールとして使った場合の各プロダクトの特長
- K2HFTFUSE が効果的なユースケース
- おわりに
- K2HFTFUSE の今後の開発
- お知らせ
Appendix
測定方法について
K2HFTFUSE とは
K2HFTFUSE は、データ集約を高速で簡単にできるようにすることを目指して作成したシステムです。
ファイルシステムとして mount しておけば、後はその場所に書き込むだけでデータは転送され、送信前後に独自の処理で加工したり多段構成で集約したりできます。
K2HFTFUSE を構成するサブコンポーネントの、
- K2HASH(ケーツーハッシュ、KVS / NoSQL ライブラリ)
- CHMPX(シーエッチエムピーエックス、通信ミドルウエア)
- K2HTPDTOR(ケーツーエッチ・ティーピーディートア、トランザクション転送プラグイン)
はプログラミングAPIが用意されていて、それぞれを単体で利用もできます。
パフォーマンス測定結果
パフォーマンス結果(ボトルネックとなる環境なし)
測定した内容
3パターンのデータファイルを用意しました。
- long: 4096 Byte x 1千万レコード / middle: 1024 Byte x 1千万レコード / short: 10 Byte x 1億レコード
このファイルをクライアント3台からサーバー1台に送信してデータ転送量を計測します。
使用した HWスペック
- Xeon E7-4850 / 4CPU
- 128GB MEM
- SAS 300GB x2 / RAID1 x 1 vol
- Network 10 Gbps
使用した環境
- OS は ubuntu 14.04 です。
- ネットワーク環境は 10Gbps で用意しました。
- K2HFTFUSE は OSS 版 1.0.23 を使用しています。
測定方法
- 3台から同時に送信を始めます。 (手動なので完全に同時ではありません。)
- 受信側で受け取ったデータを1つのファイルに集約し、10秒ごとにファイルサイズのチェックを行って、この差分から転送量を計算します。
- 送信開始20秒前後からの転送量が安定した時点から100秒間の平均値を取り、これを3回行った平均値を取ります。
データの投入方法
cat [データファイル] > [転送対象ディレクトリ]
で、投入しました。
データの集約方法
- 設定ファイルで
[K2HFTFUSESVR]FILE_UNIFY
(集約)を指定して1ファイルに集約しました。
パフォーマンス測定結果
レコード長 | 平均転送レコード数(秒) | 平均転送バイト数(秒) |
---|---|---|
10 Byte | 937,779 | 8.9 MB/S |
1024 Byte | 219,578 | 214.4 MB/S |
4096 Byte | 64,943 | 253.7 MB/S |
このパフォーマンス計測で利用した方法にはそれぞれ理由がありますので、この計測方法に至った理由を以降で説明していきます。
また、環境に依存したパフォーマンス結果の違いや、他のプロダクトとの計測結果の違いなどについても説明します。
1Gbps ネットワークでの測定(ネットワークのボトルネック環境)
上記と同様に転送量の計測を目的としたテストを 1Gbps ネットワークで行った際の結果です。 結果的にネットワーク性能が不足している場合の挙動になります。
テスト環境
- Xeon D-1541 2.1GHz 8コア,16スレッド
- 32GB MEM
- SATA SSD 400GB x1 / RAID 無
- Network 1 Gbps
テスト方法
転送量の計測は、10秒ごとに集約したファイルのライン数をカウントして計算値を出しました。
計測が終わるとファイルを削除して、作り直されたファイルに書き込んでいきます。
テスト結果
送信側1台、受信側1台で予備テストしていたときはレコード長が大きくなると転送量が増える傾向だったのですが、今回は伸び悩んでいました。
理論値ではネットワークの性能以上の速度が出ていると予想できます。計測結果もこの付近で上限に達しています。
外部からモニタリングツールで確認した結果、 実際に回線速度の上限に達していることが確認できました。
よって、今回の計測ではネットワーク上限での挙動を見ることができましたが、本来の性能は計測できていません。
また、この計測方法では、ファイル削除・作成に時間がかかっている可能性もあるので、以降は10秒ごとのファイルサイズの差分で出すことにしました。
まとめ
- 1Gbps ネットワークで K2HFTFUSE を使用した場合、ネットワークの限界以上の転送能力に留意して使用する必要がありそうです。
これは適切なウエートや送信頻度などで調整できると思います。
HDD 使用環境での測定(ファイル・デバイスのボトルネック環境)
同様にファイル・デバイスの違いによる転送量の計測を目的として SSD と HDD でテストを行った際の結果です。
結果的にファイル・デバイスの性能が不足している場合の挙動が明確になりました。
ネットワークは 10 Gbps で 検査しています。
テスト環境
- Xeon E5-2630L 2.00GHz / 2CPU
- 64GB MEM
- SAS 300GB x2 / RAID1 x 1 vol
- Network 10 Gbps
テスト方法
10秒ごとにファイルサイズをチェックして、10秒前のサイズとの差分から転送量を計算しました。
テスト結果
データサイズ middle と long で差が小さいことと、転送を継続した際にパフォーマンスが急激に下がる現象が発生したので、転送完了までの推移を確認してみました。
同時にモニタリングツールで見てみると、計測中にフリーメモリがキャッシュに割り当てられて徐々に減少し、枯渇したところで遅くなる事がわかりました。
このグラフの時は150秒付近で最高速が出なくなり、700秒付近ではフリーメモリがほぼ無くなった状態になっていました。
この計測では SSD ではなく HDD を使っているので、受信したデータを書き込む際にディスクの速度が追いつかず、最終的にメモリを使い果したと想像できます。
出力先を /dev/null にしてネットワーク帯域の使用状況を見てみると、転送完了まで途中で速度低下することなく推移したので HDD がボトルネックであると確認できました。
まとめ
- 転送量がディスク書き込み速度を上回るとメモリを使い果した後にパフォーマンスが低下します。
- HDD で K2HFTFUSE を利用する場合には、書き込み速度(転送量)を意識して運用をする必要があります。上限に達した場合には OS 全体のパフォーマンスへの影響が考えられます。
- 転送能力と言う意味では上記「時間の推移と転送量」のグラフでデータが取れていると思われますが、パケットには転送データ以外の管理用データも含まれますので、
やはり実際の書き込みまでの結果が必要だとの結論に至り、高速なファイル・デバイスのある環境で再度の計測をする事にしました。
他プロダクトとの比較測定結果
K2HFTFUSE のパフォーマンスはわかりましたが、同じユースケースで他のプロダクトを使用してみるとどうなるか、 fluentd と kafka で比較してみました。
今回パフォーマンス測定をしたプロダクトとバージョンです。
- fluentd 0.14.15
- kafka 2.10-0.10.2.0
- K2HFTFUSE 1.0.23
データの投入方法
- fluentd
cat [データファイル] > [転送対象ファイル]
で、投入しました。 - kafka
1パーティションのtopicを作成し、cat [データファイル] | kafka-console-producer.sh
で、投入しました。
そのままでは timeout 多発だったので メッセージ内容を見ながら--request-timeout-ms
を調整しています。 - K2HFTFUSE
cat [データファイル] > [転送対象ディレクトリ]
で、投入しました。
データの集約方法
- fluentd
設定ファイルでtype fileとすると自動でファイルがローテーションされ、最新ファイルへのシンボリックリンクが作成される仕組みになっています。
このままでは他のプロダクトと同じ条件での計測が難しいので、type stdout として画面出力したものをファイルにリダイレクトして1ファイルに集約します。 - kafka
kafka-console-consumer.sh の出力をファイルにリダイレクトして使用しました。 - K2HFTFUSE
設定ファイルで [K2HFTFUSESVR]FILE_UNIFY(集約)を指定して1ファイルに集約しました。
通常の生ログ(RAW)での出力に加え、fluentd に合わせた JSON 出力の結果も計測しました。
パフォーマンス測定結果
K2HFTFUSE(JSON)が最も良いパフォーマンスとなりました。 これは、転送バイト数の計測を受信サーバーで行っており、JSON 形式の場合は JSON に変換後のサイズで計測されているためです。(K2HFTFUSE(JSON)とfluentdの計測の場合)
10 Byte レコードと比較すると、kafka はレコードサイズの大きなデータの方がパフォーマンスが良いという傾向でした。
今回のユースケースでは、 どのサイズのデータでも K2HFTFUSE が一番良いパフォーマンスとなりました。
まとめ
K2HFTFUSE の性能について
K2HFTFUSE の性能は、10Gbps のネットワークと高速なストレージを準備して初めて上限に達しました。
それ以下の環境で利用する際には、K2HFTFUSE の限界よりも先に、ネットワークやディスク書き込み速度が上限に達します。
よって、既存の大多数のシステム上で K2HFTFUSE の限界を気にせず有効に使うことができます。
各プロダクトとの比較
各プロダクトの設定作業について
それぞれのプロダクトのインストールや設定作業を行った際の特長や所感です。
- K2HFTFUSE
設定ファイルの項目が多いので最初が難しいかもしれませんが、記述の必要な項目は少ないので、サンプルの提供やマニュアルの充実で対応できそうです。
設定ファイルをコピーするだけでクラスタ化できます。 - fluentd
コマンド1発でインストールでき、一番簡単に設定作業が終わりました。 自分で設定できる通信パラメーターは少ないようです。
設定ファイルを用意したあとは、コピーするだけでクラスタ化できます。 - kafka
kafka独自の用語が多いと感じたため難易度も高いと感じましたが、意外と簡単に動作させることができました。
ただし、他のプロダクトと比較して必読のドキュメントが多く、また自作プログラムからの利用が前提となっているので、使いこなすまでに至るのは時間がかかると感じました。
稼働させるには zookeeper の設定をして、kafka の設定をした上で topic の作成という手順でした。
設定ファイルをコピー後に broker id を編集することでクラスタ構成にできました。
ログ収集ツールとして使った場合の各プロダクトの特長
各プロダクトをログ収集ツールとして使った場合の特長です。(本来の使用用途と異なるのかもしれませんが)
- データ整形機能
- K2HFTFUSE
単純な文字列置換は設定ファイルだけでできます。 自作プラグインを作りやすいのも特長です。 - fluentd
豊富なプラグインを活用すれば自作する必要がありません。 - kafka
自作前提のようです。
- K2HFTFUSE
- クラスタ関連機能
- K2HFTFUSE
CHMPX を使って高機能を実現しています。 - fluentd
ロードバランシングのみ利用できます。 - kafka
zookeeper を使って高機能を実現しています。
- K2HFTFUSE
- 複数ファイルの取り扱い
- K2HFTFUSE
ディレクトリだけ指定しておけばできます。 - fluentd
公式サイトで配布しているプラグインで実現します。 - kafka
自分で複数 topic を作成します。
- K2HFTFUSE
- 速度
- K2HFTFUSE
今回測定したレコード長全般で良いパフォーマンスでした。 - fluentd
速度よりも使いやすさを重視しているようです。 - kafka
大きめのレコードやネットワーク回線の能力ギリギリでの送信に強いようで、1Gb ネットワーク環境での long サイズレコードで高パフォーマンスとなりました。
これは送信時にデータ圧縮をしているからだと思われます。
- K2HFTFUSE
- 安定度
- K2HFTFUSE / fluentd
一度稼働させてしまえば運用であまり手間のかからない印象でした。 - kafka
topic の手動操作など、できることが多いのですが、代わりに障害対応にはある程度の熟練が必要と感じました。
- K2HFTFUSE / fluentd
K2HFTFUSE が効果的なユースケース
今回は、K2HFTFUSE の想定しているユースケースのひとつである、ログ転送を主目的としたパフォーマンスの調査をしました。
結果として、ログ転送において想定以上のパフォーマンスを確認できました。
この結果から、
- 大量のデータが書き込まれるログを転送する。
- 多数のファイルに吐かれるログを転送、集約する。
- 転送データの加工をする。(今回はJSON形式で試行)
- データ加工を簡単にプロトタイプとして試行する。
などといったユースケースが効果的だと思います。
また、他のプロダクトと比較したときの、
- 稼働後にサーバーのスケール(追加や削除)を頻繁に行うケース。
- 最小限のマニュアルでシステム運用チームに引き渡す。
という特長を活かせる場面も多いと思います。
おわりに
今回は比較対象として同じような機能を持っている fluentd と kafkaと比較してみましたが、私はこの2つのプロダクトのプロフェッショナルではありません。
そのため、これらのプロダクトについて精通している方がチューニングして計測した場合はもっと良い結果になると思います。
同じユースケースでチューニングした結果があればぜひとも公開していただければと思います。
また、他のユースケースでの計測結果があれば K2HFTFUSE でも検査をしてみたいと思います。
K2HFTFUSE の今後の開発
今回の結果を踏まえて、私たちは K2HFTFUSE をさらに簡単に使えて、他のプロダクトの運用ノウハウも使えるような、そんな機能改善の検討を始めました。
近日中に公開できるように励みます。
お知らせ
K2HFTFUSEのサブコンポーネントのAPIマニュアルを公開しました。
高パフォーマンスを実現している内部コンポーネントのKVSライブラリ、通信ミドルウエア、ロックライブラリを C/C++ から簡単に使う事ができます。
サンプルコードやそれぞれのコンポーネントの紹介もこれから順次公開していきたいと思います。
今回 K2HFTFUSE で使用した設定ファイルは wiki にて近日中に公開する予定です
最後に、長文をお付き合いいただきましてありがとうございました。 続編にご期待ください。
Appendix
測定方法について
測定方法に至るまでの準備や試行錯誤を簡単に紹介します。
インストール
弊社内の開発用サーバーとネットワークを手配して各プロダクトのインストールと、チュートリアルにある疎通確認までをやってみました。
今回比較対象にした fluentd と kafka ですが、私自身は今まで利用した経験がなかったので情報収集しながらのインストールとなりました。
予備テスト
疎通ができたので、今度はデータファイルとサーバー構成を変えながら計測してみます。
- 送り側1台、受け側1台で小規模なデータを流してみる
100 Byte x 1千万レコードの送信開始から送信終了までの時間を測定しました。 - データサイズを変えてみる
レコード数を1億、レコード長を 32 / 256 / 1024 Byte の 3パターンで用意し、それぞれが受信側でファイルを書き終わるまでの時間を3回測定して平均値を取りました。 - 複数台から送信してみる
レコード長 32 Byte のデータを使って送信側を 2台、3台と増やしてみます。
この結果を参考にして専用環境でテストする際の計測方法やデータサイズをあらためて検討しました。
- テストデータ長
今までは最大 1024 Byteで計測していましたが、もっと大きなサイズを準備しておけば多くのケースの指標になると考え、本番の計測では最大長を 4096 Byteにする事に決めました。 - 計測方法
純粋な転送能力を測定したいので受信側で集約したファイルを、10秒ごとの行数カウントとファイル削除を行い理論値を計算することにしました。 これによって送信側の影響を取り除くことを試みています。 - 計測区間
それぞれのプロダクトで試したところ、転送を開始から安定的に速度が出るのに20秒程度かかっていましたので、ここからを計測区間とすることにしました。
こちらの記事のご感想を聞かせください。
- 学びがある
- わかりやすい
- 新しい視点
ご感想ありがとうございました