株式会社クリアコード > ククログ

ククログ


Fluentdのベンチマークツールの開発

はじめに

クリアコードはFluentdの開発に参加しています。

Fluentdにはプラグインというしくみがあり、たくさんのプラグインが開発されています。
Fluentdのプラグインでは各種APIを使用しており、プラグインによって消費するリソースの傾向が異なるということがあります。
今回そのリソースの傾向はどの程度なのかを知るために筆者畑ケがベンチマークツールを開発し、傾向を測定しました。

Windows EventLogを扱うプラグイン

Windows EventLogを引っ張ってくるプラグインは https://github.com/fluent/fluent-plugin-windows-eventlog にて開発されています。Fluentdの開発チームはwin32-eventlog gemでは対処しきれないEventLogの形式があることから、winevt_c gemを開発しています。
このgemは基本的にCで書かれているため、大きなボトルネックになることはありませんが、リソースの消費傾向を把握するのは重要と考えています。

Fluentdのベンチマークの考え方

FluentdのInputプラグインやOutputプラグインは基本的にある間隔で動作します。また、Outputプラグインはすぐに送ることはせずにbufferingをします。このことから、Fluentdが消費しているリソースを時間ごとにモニタリングした生データを単にプロットするだけではどの程度のリソース消費をするかが判りにくくなります。
リソースの消費傾向は中央値(メジアン)・25パーセンタイル〜75パーセンタイルの範囲、そして99パーセンタイル程度の測定値がどの程度の範囲内にあるかを図示した方がリソースの消費傾向が分かりやすくなります。

箱ヒゲ図(Box Plot)とは

箱ヒゲ図とは、データのばらつきを分かりやすく表現するためのグラフの一種です。 例として以下の図にあるような箱ヒゲ図を見てみます。

(https://towardsdatascience.com/understanding-boxplots-5e2df7bcbd51 より引用)

この箱ヒゲ図では、真ん中の箱の範囲に25パーセンタイルから75パーセンタイルの中位50パーセンタイルの数値が入ります。
また、下ヒゲから箱の下までが下位24.65パーセンタイル、上ヒゲから箱の上までが上位24.65パーセンタイルの数値が入ります。下ヒゲから上ヒゲまでが99.3パーセンタイルの数値が入ります。時折生じるリソース消費のスパイク現象を除いたリソースの消費量を見るには、下ヒゲから上ヒゲの99.3パーセンタイルの範囲の数値をみると良いことになります。

この箱ヒゲ図を正規分布に対応させると以下のようになります。

(https://towardsdatascience.com/understanding-boxplots-5e2df7bcbd51 より引用)

ただし、この箱ヒゲ図には重要な仮定があります。値の分布が正規分布*1 に従っている*2という条件があります。

ベンチマーク環境の作成

こちらはTerraformを用いてAzureにベンチマーク環境を整えることで実施しました。
また、ベンチマーク後のグラフの描画にはmatplotlibを基にしたseabornを用いています。

Windows EventLogのベンチマークを実施する
ベンチマークの準備

まず、Python3の環境をセットアップします。ベンチマーク環境を整備するにはpython3のインストールが必要です。
ここでは、ホスト環境がUbuntuであると仮定します。

$ sudo apt install python3 python3-venv build-essentials

ベンチマーク環境をセットアップするスクリプトをgit cloneします。

$ git clone https://github.com/fluent-plugins-nursery/fluentd-benchmark-azure-environment.git
$ cd fluentd-benchmark-azure-environment

venvを使ってシステムのPython3環境と分離します。

$ python3 -m venv management
$ source management/bin/activate

requirements.txtを使って必要なPython3のライブラリをインストールします。

$ pip3 install -r requrirements.txt

Ubuntuで実行可能なTerraformを https://www.terraform.io/downloads.html からダウンロードして来てインストールします。
この記事ではWindows EventLogのベンチマークの実行を例にするため、winevtlog_benchディレクトリにcdします。

$ cd winevtlog_bench

Terraformを初期化して、必要なProviderをダウンロードします。

$ terraform init

terraform.tfvars.sampleをコピーします。

$ cp terraform.tfvars.sample terraform.tfvars

以下の変数の値を実際に使用するものに書き換えます。

linux-username       = "admin"
linux-password       = "changeme!"
region               = "Japan East"
windows-username     = "admin"
windows-password     = "changeme"
ssh-private-key-path = "/path/to/private_key"
resource-group       = "ExampleGroup"

ssh-keygenを用いてid_rsa_azureというRSA 2048ビットの秘密鍵と公開鍵を生成します。id_rsa_azure.pubを、azure_keyというディレクトリに格納します。

Azureの認証情報は Terraformの導入 - 検証環境をコマンドで立ち上げられるようにする その1 を参考に取得します。
env.shをコピーし、

$ cp env.sh.sample env.sh
#!/bin/sh

echo "Setting environment variables for Terraform"
export ARM_SUBSCRIPTION_ID=<SUBSCRIPTION_ID>
export ARM_CLIENT_ID=<APP_ID>
export ARM_CLIENT_SECRET=<APP_PASSWORD>
export ARM_TENANT_ID=<TENANT_ID>

スクリプト中の角かっこの値を埋めて、env.shを読み込みます。

$ source env.sh

また、AzureのCLIでのログインは事前に行っておいてください。

ここまででTerraformを使ったベンチマーク用のAzureインスタンスを建てる準備が整いました。

ベンチマークの実施

ベンチマークの実施方法はMakefileとAnsible Playbookに集約されているので順番に実行していけば良いです。

$ make apply

により、Azure上にベンチマーク用のインスタンスが建ちます。

$ make provision

により、ベンチマークに必要なライブラリやツールが建てたAzureのインスタンスにダウンロードされ、インストールされます。

Windows EventLogの単純なベンチマークは、

$ make windows-bench

により実施されます。このコマンドを実行すると、裏ではAnsible Playbook化されたタスクが走ります。
このタスクはWindows上で採取されたデータを収集する部分まで含まれます。

ベンチマーク結果の可視化には次のコマンドも実行します。

$ make visualize

このコマンドにより、ベンチマーク結果を箱ヒゲ図で可視化できます。
ベンチマークが終わった後は、ベンチマークに使ったAzureインスタンスを破棄してしまいましょう。

$ make clean

ベンチマーク結果の一例

CPUの消費傾向を箱ヒゲ図で見てみます。
また、記事中では解説していませんが、外れ値があるかどうかもチェックしたいため、strip plotで実際の値も箱ヒゲ図に重ねてプロットしています。小数点以下第3位で四捨五入したメジアンの値ラベルについても、箱ヒゲ図に重ねてプロットしています。
およそ12分で120000イベントのWindows EventLogをin_windows_eventlog2で受け取った場合のFluentdのワーカーのCPU使用率です。

おおよそ1分間に159イベント程度を決められたチャンネルに書き込む流量があります。
このベンチマークでは、イベントの流量とサイズが大きくないため、ワーカープロセスのCPU使用率には差が出ていません。

ワーカープロセスのメモリ使用量はどうでしょうか。

こちらは、受け取ったメッセージサイズに多少影響を受けるところが見て取れます。

まとめ

Fluentdのプラグインのベンチマークの方法を解説してみました。
Windows向けに開発したプラグインでは、Linux向けとは違うリソースを消費する傾向になってしまう事があります。
Windows EventLogを扱う際にはWindowsが提供するAPI経由となるため、Cで書いている箇所に関しては大幅なボトルネックとなってしまう箇所が少ない事が確認できました。
また、ある程度の流量にも耐えられうる状態で提供できていることも確認できました。

*1 https://www.mathsisfun.com/data/standard-normal-distribution.html

*2 実際には正規分布というよりもリソースは有限なので下位側に潰れた分布になりますが、議論を簡単にするためこの仮定を置いて問題はないでしょう。

タグ: Fluentd
2020-07-07

«前の記事: ノータブルコード9 - C言語で文字列を扱うときはNULL終端されているかどうかに注意する 最新記事 次の記事: ノータブルコード10 - 文芸的設定ファイル »
タグ:
年・日ごとに見る
2008|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|