shiimaxx's blog

最も愛を大切に

Mackerelで負荷テスト中のリソースモニタリングを行う

Mackerel Advent Calendar 2019 22日目のエントリです。


Mackerelでは、ホストやミドルウェアのメトリックをグラフとして可視化することができます。日々のシステム状況の把握やキャパシティプランニング、トラブルシューティングの際に参照するのが主な用途だと思いますが、システムの運用を開始する前の負荷テストにおいても活用することができます。

本エントリでは、時系列データベースGraphiteの書き込みパフォーマンスの負荷テストを例にして、Mackerelによる負荷テスト中のメトリックの可視化とそれを活用してチューニングする過程を紹介します。

ひとつ注意点があります。Mackerelではメトリックを1分間隔で保持するので、負荷計測を短時間(数十秒〜数分)で行うケースではデータの解像度が足らずうまく利用することができません。
これから紹介するのは「ある想定したワークロードを継続的に問題なく処理できるか」を検証するために、数十分以上継続して負荷計測するケースです。

Graphite

はじめに計測対象のGraphiteについて説明します。
Graphiteは以下のコンポーネントで構成される時系列データベースです。

  • Graphite-Web
  • Carbon
  • Whisper

コンポーネントの連携については次の図が参考になります。

https://raw.githubusercontent.com/graphite-project/graphite-web/master/webapp/content/img/overview.png

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

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時間程度実行したあとのグラフです。

f:id:shiimaxx:20191221203650p:plain

f:id:shiimaxx:20191221203749p:plain

f:id:shiimaxx:20191221203840p:plain

f:id:shiimaxx:20191221203915p:plain
※ データディスク(Graphitデータ保存先)のWrite数のグラフ

送信側の並列数が増えるにつれて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時間程度実行したあとのグラフです。

f:id:shiimaxx:20191221204136p:plain

f:id:shiimaxx:20191221204209p:plain

f:id:shiimaxx:20191221204223p:plain

f:id:shiimaxx:20191221204235p:plain
※ データディスク(Graphitデータ保存先)のWrite数のグラフ

送信側の並列数が増えるにつれて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のグラフは各インスタンスの値が個別の線で表示されていますが、各インスタンスの値の合計がわかりやすいようにグラフを積み上げにしています。

f:id:shiimaxx:20191221204530p:plain

負荷計測を1時間程度実行したあとのグラフです。

f:id:shiimaxx:20191221204717p:plain

f:id:shiimaxx:20191221204733p:plain

f:id:shiimaxx:20191221204746p:plain

f:id:shiimaxx:20191221204801p:plain
※ データディスク(Graphitデータ保存先)のWrite数のグラフ

Carbon Metrics ReceivedCarbon Committed Pointsは先ほどと同じで300万程度まで増えています。

CPUはidle以外の合計が400%近くまで増えましたが、その半分をiowaitが占めています。ディスクは5000IOPSが続いており、I/O性能を上限まで使い切れています。さきほどよりIOPSが増えている理由は特に調べていませんが、carbon-cacheのインスタンスを4つにしたことで、今まで1つのプロセスで書き込みをしていたのが4つのプロセスで書き込みするようになったため、書き込みのマージが効きづらくなったのかもしれません。

まとめ

少し前に業務でGraphiteサーバの負荷テストをやりまして、そのときはモニタリングは独自基盤を利用していたのですが、Mackerelでもできそうということでやってみました。

エージェント・メトリックプラグインダッシュボードがいい感じに連携していて、本当に少しの作業でグラフが作れてとても便利ですね。

参考文献