「Understanding Metrics in the Age of the TSDB」を読んだ時のメモ

CloudFlareの人がメトリクスについて書いたブログ記事を読んだ時のメモ。

※「あれ、このドメインは...?」と思う方もいると思いますが、そうです、HeartbleedのチェックサイトとかCVE-2016-2107のチェックサイトをつくっていたあの人です。

Think for example to the Unix load averages, those three numbers shown in top to give you an idea of how loaded the machine has been in the last minutes. 3.9 3.1 1.2 would tell you, for example, that the machine has been doing 400% for the last 3 to 6 minutes--not 1, not 20.

topコマンドの上に出る3つの数字。あれって直近1分、5分、15分の単純な平均だと思ってたんですけど、指数移動平均(exponentially weighted moving average、EWMA)というやつらしいです。なにそれ?、という話はおいておいて読み進めます。

We'll refer to the terminology of the Metrics Java library, a port of which is the most popular Go metrics library.

Metricsは、その名のとおりメトリクスを扱うためのJavaのライブラリです。いろんな言語にポーティングされていて、みんな大好きGoもあります。このMetricsで使われている用語を借りて説明しますよ、と。

Metricsのメトリクスの種類は色々ありますがここで登場するのは主にこのへんです↓

  • Gauge: 任意の値(例:CPU負荷)
  • Counter: 単調増加する値(例:エラーの回数)
  • Meter: 割合、頻度(例:エラー率)
  • Histogramヒストグラム

で、Meterはいまいちだ、と。

(略)for example the 1-minute EWMA will add up 63% of the rate from the last 60s, plus 37% of the rate since start to 60s ago. The code might be clearer. A graph of a EWMA is slow to change, and probably not what you want unless you really understand what a EWMA shows.

例えば1分間隔のEWMAは、直近1分間の値の影響が63%、それより前の値の影響が37%の平均だ(この計算よくわからない)…。こういう計算の仕方なのでEWMAのグラフは変化しづらい。変化を見つけづらい。

それより前の値って??と思ったら、こういう文章が続いていました。

The mean rate instead is as simple as it is useless. It's just total events divided by seconds since start.

どうもここで言っているEWMAは、「moving」と言いつつsliding windowみたいなのはなくて、計測開始からの累計値に対してのEWMAのことを指しているようです(そういうものなの?)。それはたしかに役に立たなそう…。たぶんその方が、どの値がいつ記録されたかとかをいちいち記録しておかなくてすんで省エネなんですね。きっと。

その次にHistogramが登場します。

But not all events are discrete, some have values of which we want to keep track. Like, how long it took to serve each HTTP request. This is what the library addresses with a Histogram.

The fundamental concept is that you can't easily visualize all the individual measures, so you have to compute some numeric distribution statistics.

値をそのまま保存して使うことが難しい場合は、平均とか中央値とか分散とか、値の集合の特徴を捉える値を使いましょう。

it's reasonably easy to keep a buffer of the last N values, or of the values from the last N seconds, and to store the statistics computed over those.

もちろん、計測し始めからの値にたいして計算するんじゃなくて、sliding window使おうよまじで、と。(でもgo-metricsには用意されていないらしい…)

EWMAのように「計測開始時からの値を重み付けでいい感じに変形すればいいんじゃね?」という手法は、バックエンドにいい感じのストレージがなくて、グラフを描いて可視化するということもなかった時代のテクニックです。

If performance allows, an alternative approach is to delegate the distribution analysis to an external system. You send all raw measurements (like, one for each HTTP request) to a different system, and that system does the statistics and exports them to the TSDB.

パフォーマンス的に大丈夫そうなら、生の値をTSDBに突っこんで、計算は別のやつに任せるのがいい。

たしかに。アッハイ。(みんなもうやってるよね…?)

感想

EWMAって知らなかったので勉強になりました(小並感)