StatsDとは何か。具体的な中身について。
この記事では、監視などの分野で出てくる StatsD についてまとめておく。
StatsD とは、様々なメトリクス(数値データ)を送信するためのプロトコルとサーバアプリケーションのことを指す。言い換えると、障害やパフォーマンスの監視などを目的として、マシンの様々なメトリクス(CPU 使用率、メモリ使用率など)を集めるためのものである。基本的な構成としては以下のようになる。
クライアント | (随時データ送信) | v サーバ (StatsD など) | (蓄積し、定期的にデータ送信*) | v モニタリング用のサーバ (グラフなどを表示する)
*定期的にデータを送信したり、データをクリアすることをフラッシュと呼ぶことが多い。
サーバアプリケーションの StatsD
サーバアプリケーションの StatsD はこちら。CloudWatch Agent など、他のソフトウェアに組み込まれている場合もある。
StatsD プロトコル
基本形と例は以下のとおり。このようなデータが UTF-8 で UDP パケットに乗るだけである。レートについては後述するが、タイプによって有る場合と無い場合がある。
# フォーマット <メトリクス名>:<値>|<タイプ>|@<レート> # 例 hoge:1|c|@0.1
以下の画像はメトリクス名: "test-client.stat1"、値: "42"、タイプ: "c" (Counter タイプ) のメトリクスを送信した例である。 "test-client.stat1:42|c" という文字列が見える通り、非常に単純な構造であることがわかる。
メトリクスのタイプ
メトリクスのタイプには厳密に定義された仕様がなく製品によって異なるので、都度ドキュメントを確認するべし。
Gauge
値の推移を計測するためのタイプ。クライアントはそのタイミングでの計測値などを送信し、サーバは受け取った値をそのまま記録する (+/- する場合もある)。サーバはフラッシュまでにデータを受け取らなかった場合、前回のデータを保持する。温度などの数値の推移を計測する場合などに使われる。
# フォーマット <メトリクス名>:<値>|g # サーバの動作例 tempreture:21|g| を受け取る -> tempreture = 21 を保持 フラッシュ -> 21 を送信 ... (データなし) フラッシュ -> 21 を送信 tempreture:-1|g| を受け取る -> tempreture = 21 - 1 = 20 を保持 フラッシュ -> 20 を送信
Set
任意の値を送信するためのタイプ。クライアントはそのタイミングでの計測値などを送信し、サーバは受け取った値をそのまま記録する。Gauges のように前回のデータを保持することはない。
# フォーマット <メトリクス名>:<値>|s # 使用例 param:21|s|
Counting (Count)
カウント数を計測するためのタイプ。クライアントは何らかのカウント数を送信し、サーバは受け取った値を +/- していく (つまり累積値)。フラッシュされると 0 に戻る。
# フォーマット <メトリクス名>:<値>|c|@<レート> # メトリクスの例 hoge:1|c| -> +1 カウント hoge:2|c|@0.1 -> +2 / 0.1 = +20 カウント # サーバの動作例 フラッシュ -> hoge = 0 hoge:1|c| を受け取る -> hoge = 0 + 1 = 1 hoge:13|c| を受け取る -> hoge = 1 + 13 = 14 hoge:-5|c| を受け取る -> hoge = 14 - 5 = 9 フラッシュ -> hoge = 0
Timer (Timing, Histogram)
ms 単位での計測時間を送信するためのタイプ。サーバ側は各データを保存し、サーバ側で統計値 (最大値, 最小値, 平均など) を計算する。製品によるが、「Timer == Timing」、「Histogram は Timer のエイリアスである」、「Timer は Histogram のサブセットである」など、まとめて扱われる場合が多い。通常、タイプを示す文字列として、Timer / Timing は ms を、ヒストグラムは h を使う。
# Timer / Timing のフォーマット <メトリクス名>:<値>|ms|@<レート> # ヒストグラムのフォーマット <メトリクス名>:<値>|h|@<レート> # サーバの動作例 フラッシュ -> load = [] load:100|ms| を受け取る -> load = [100] load:120|ms| を受け取る -> load = [100, 130] load:400|ms| を受け取る -> load = [100, 130, 400] フラッシュ -> max = 400, min = 100, avg = 210 を送信 / load = []
メトリクスのレート
クライアントでのサンプリング間隔 ÷ サーバへのデータ送信間隔を示す。例えば、1 分毎にサンプリングして 5 分毎に送信する場合、1/5 = 0.2 ということになる。クライアントからサーバへの送信回数を減らして、負荷を抑えるためにこのような仕組みが用意されている。
受け取ったサーバはこれを考慮し、例えば "hoge:1|c|@0.1" であれば、通常 1 / 0.1 = 10 カウントとして記録することになる。"load:100|ms|@0.2" の場合、おそらく load += [100, 100, 100, 100, 100] という換算になるのだと思われる。