Mackerelで負荷テスト中のリソースモニタリングを行う
Mackerel Advent Calendar 2019 22日目のエントリです。
Mackerelでは、ホストやミドルウェアのメトリックをグラフとして可視化することができます。日々のシステム状況の把握やキャパシティプランニング、トラブルシューティングの際に参照するのが主な用途だと思いますが、システムの運用を開始する前の負荷テストにおいても活用することができます。
本エントリでは、時系列データベースGraphiteの書き込みパフォーマンスの負荷テストを例にして、Mackerelによる負荷テスト中のメトリックの可視化とそれを活用してチューニングする過程を紹介します。
ひとつ注意点があります。Mackerelではメトリックを1分間隔で保持するので、負荷計測を短時間(数十秒〜数分)で行うケースではデータの解像度が足らずうまく利用することができません。
これから紹介するのは「ある想定したワークロードを継続的に問題なく処理できるか」を検証するために、数十分以上継続して負荷計測するケースです。
Graphite
はじめに計測対象のGraphiteについて説明します。
Graphiteは以下のコンポーネントで構成される時系列データベースです。
- Graphite-Web
- Carbon
- Whisper
各コンポーネントの連携については次の図が参考になります。
Graphiteにおいてメトリックを受信して書き込みを行うのはCarbonです。Carbonはデーモンとして稼働し、ネットワーク経由でメトリックを受信してそれをWhisper形式でファイルに書き込みます。
負荷テストではCarbonに対して大量のメトリックを送信することで負荷計測を行います。
検証環境
サーバ構成
- サーバ
- Microsoft Azure Standard F4s_v2(4 vcpus, 8 GiB memory)
- データディスク(Graphitデータ保存先)
- Premium SSD Managed Disks P30 (1024 GiB, 5000IOPS, 200 MB/second)
- OS
- Ubuntu Server 18.04 LST
Mackerelメトリックプラグイン
Graphiteのメトリック可視化のためにmackerel-plugin-graphiteを使います。
Graphiteは自身の統計情報を時系列データとして保持しています。mackerel-plugin-graphiteはこれをGraphite-Web経由で収集するプラグインです。
今回の負荷テストで主に確認するメトリックは次の2つです。
- Carbon Metrics Received
- 受信したメトリックのデータポイントの数
- Carbon Committed Points
- ディスクにフラッシュしたメトリックのデータポイントの数
受信したメトリックを遅延なくディスクにフラッシュできているかという、Graphiteの書き込みパフォーマンスに直結する値がここから読み取ることができるためです。
負荷テストツール
haggarというCarbonの負荷テストツールを使います。
haggarでは、並列数・メトリック数・メトリックの送信間隔などをオプションで指定してどの程度の負荷(メトリックの送信量)をかけるかを調整します。
以下は負荷調整に利用するオプションのデフォルトです。
$ haggar \ -agents=100 \ -flush-interval=10s \ -metrics=10000 \ -jitter=10s \ -metrics=10000 \ -spawn-interval=10s
デフォルトは次のような負荷のかけ方になります。
- 10秒(+最大10秒のゆらぎ)ごとに並列数を増やし(
-spawn-interval
,-jitter
) - 最大100並列で(
-agents
) - それぞれ10000個のメトリックを(
-metrics=10000
) - 10秒間隔でフラッシュする(
-flush-interval
)
構築手順
負荷テスト開始時点までの構築手順を以下に載せています。
https://gist.github.com/shiimaxx/53b8dfe76b5f13bbff9f75777293e0f4
負荷計測
それではhaggarで負荷計測しつつ、Mackerelのグラフを見てみます。
haggarは次のように実行しました。最大並列数を300でそれぞれ2000個のメトリックをフラッシュします。その他はデフォルトです。
$ haggar -agents=300 -metrics=2000 -carbon=localhost:2003
負荷計測 - 1回目
負荷計測を1時間程度実行したあとのグラフです。
送信側の並列数が増えるにつれてCarbon Metrics Received
が200万程度まで増えていっていますが、それと比較してCarbon Committed Points
は1万くらいにしかなっていません。
メトリックの受信量に対してディスクへのフラッシュが追いついていないという状態です。
サーバリソースのグラフを見ると、CPUリソースは1コア分しか利用していません。また、データディスクは5000IOPSが上限のものを利用していますが、グラフでは10〜60IOPS程度です。
サーバリソースにまだ余裕があることから、サーバの性能不足によってGraphiteのデータ書き込みが追いついていないというわけではないことがわかります。 このようなケースでは、何かしらのエラーやミドルウェアの設定によってパフォーマンスが制限されている場合はあります。
Graphiteでは、MAX_UPDATES_PER_SECOND
というパラメータでメトリック更新のためのディスク書き込みのレートを設定することができます。デフォルト値は500です。
この設定によってCarbonがメトリックをディスクに書き込む動作が制限されていた可能性があるので、設定を変更します。
設定値をinf
にすると書き込みレートの制限がされません。また、メトリックの新規作成時の書き込みレートも同じように制限しないようにします。
/etc/carbon/carbon.conf
[cache] ... MAX_UPDATES_PER_SECOND = inf MAX_CREATES_PER_MINUTE = inf
負荷計測 - 2回目
設定変更後に再度負荷計測を実行します。負荷計測を1時間程度実行したあとのグラフです。
送信側の並列数が増えるにつれてCarbon Metrics Received
が300万程度まで増えていっています。先ほどとは違いCarbon Committed Points
も300万程度まで増えており、受信したメトリックをしっかりディスクにフラッシュできているようです。
CPUはiowaitの割合が少し目立ってきました。ディスクは2000〜3000IOPSを推移しています。
Graphiteの書き込みパフォーマンスは特に問題ありませんが、せっかく4vcpusのVMを利用しているので、vcpuの数分carbon-cacheのインスタンス起動してcarbon-relayでバランシングする構成に変更したときにどのような傾向になるかも見てみます。
/etc/carbon/carbon.conf
[cache:b] LINE_RECEIVER_PORT = 2103 PICKLE_RECEIVER_PORT = 2104 CACHE_QUERY_PORT = 7102 [cache:c] LINE_RECEIVER_PORT = 2203 PICKLE_RECEIVER_PORT = 2204 CACHE_QUERY_PORT = 7202 [cache:d] LINE_RECEIVER_PORT = 2303 PICKLE_RECEIVER_PORT = 2304 CACHE_QUERY_PORT = 7302 [relay] RELAY_METHOD = consistent-hashing DESTINATIONS = 127.0.0.1:2004:a, 127.0.0.1:2104:b, 127.0.0.1:2204:c, 127.0.0.1:2304:d
/lib/systemd/system/carbon-cache@.service
[Unit] Description=Graphite Carbon Cache %i After=network.target Documentation=https://graphite.readthedocs.io [Service] Type=forking StandardOutput=syslog StandardError=syslog ExecStart=/usr/bin/carbon-cache --config=/etc/carbon/carbon.conf --instance %i --pidfile=/var/run/carbon-cache-%i.pid --logdir=/var/log/carbon/ start PIDFile=/var/run/carbon-cache-%i.pid [Install] WantedBy=multi-user.target
carbon-cacheを停止して、carbon-cache@a 〜 carbon-cache@dとcarbon-relay@aを起動する。
$ sudo systemctl stop carbon-cache $ sudo systemctl start carbon-cache@a $ sudo systemctl start carbon-cache@b $ sudo systemctl start carbon-cache@c $ sudo systemctl start carbon-cache@d $ sudo systemctl start carbon-relay@a
負荷計測 - 3回目
メトリックの送信先をcarbon-relay(2013ポートで待受け)にします。
$ haggar -agents=300 -metrics=2000 -carbon=localhost:2013
carbon-cacheのグラフは各インスタンスの値が個別の線で表示されていますが、各インスタンスの値の合計がわかりやすいようにグラフを積み上げにしています。
負荷計測を1時間程度実行したあとのグラフです。
Carbon Metrics Received
とCarbon Committed Points
は先ほどと同じで300万程度まで増えています。
CPUはidle以外の合計が400%近くまで増えましたが、その半分をiowaitが占めています。ディスクは5000IOPSが続いており、I/O性能を上限まで使い切れています。さきほどよりIOPSが増えている理由は特に調べていませんが、carbon-cacheのインスタンスを4つにしたことで、今まで1つのプロセスで書き込みをしていたのが4つのプロセスで書き込みするようになったため、書き込みのマージが効きづらくなったのかもしれません。
まとめ
少し前に業務でGraphiteサーバの負荷テストをやりまして、そのときはモニタリングは独自基盤を利用していたのですが、Mackerelでもできそうということでやってみました。
エージェント・メトリックプラグイン・ダッシュボードがいい感じに連携していて、本当に少しの作業でグラフが作れてとても便利ですね。