VictoriaMetricsを使ってよりよいPrometheus rate()関数

gavin.zhou
7 min readJun 2, 2020

私のPrometheus が大好きなポイントはたくさんあります。Prometheus のデータモデルはアプリケーションを監視するのに最適ですし、PromQL 言語は可観測な空間でのデータ検索のニーズに対して SQL よりも表現力があることが多いです。しかし、一つだけ大嫌いなところがあります。それは、rate()や類似の関数のビヘイビアです。開発チームから言われたPrometheusの計算モデルに深く根ざしたもので、それはどうしても変わらないようです。

So What’s the Problem, and Why is it Such a Big Deal?

それでは、何が問題で、なぜそれがそんなに問題になるのでしょうか。最初に問題についてです。 rate()関数は与えられた間隔の時系列の変化率を与えてくれるので、 rate(mysql_global_status_questions[10s])は基本的に最後の10秒間のMySQL Questionの平均数を教えてくれます。今のところすべてが素晴らしいです。

しかし、この時系列のresolutionが10秒以下だったとしたらどうでしょうか。例えばmysql_global_status_questionsの測定を1分毎にしか取らなかった場合はどうでしょうか?この場合、rate()関数は何も返さず、グラフからデータが消えてしまいます。

What would I like to see instead?

その代わりに何が見られるのでしょうか?常識的な答えを出してください! MySQL Questionが0:00に1M、10:00に2Mだったと言って、4:00から5:00までの1秒あたりの平均クエリー数を聞いても、利用可能なデータに基づいて、利用可能な最高の推定値を使って平均値を出すだけです。

もちろん、このようなアプローチには問題がないわけではありません。例えば、MySQLは5:00 に10Mのクエリを実行し、再起動したときには2Mになっていて、データが間違っている可能性もあります。しかし、ほとんどの場合、このようなデータを持っている方が、データが利用できないよりも好ましいと私は考えています。

Existing “Solutions”

Prometheusがこの問題に対して提案している「解決策」の一つが irate() 関数です。これは時系列の最後の二つのデータポイントに基づいた「instant rate(瞬間率)」を提供してくれます。irate() を十分に大きな間隔で使えば、「データなし 」を避けることができますが、また別の問題が発生します。つまり、2つの測定値に基づいた非常に不安定なデータを得ることになります。それは、より少ないvolatile値の間に、より長い期間にわたってスムーズになっており、こういうものが望まれていると思います。

irate()のもう一つの問題点は、rate()関数だけがそのような対応関数を持っていて、avg_over_time()やmax_over_time()のような他の関数は素晴らしいオプションを持…

--

--