久しぶりのAdventカレンダー挑戦、うまくいく気がしません。
閑話休題。実のところ、rate()関数というよりは、サーバー側のmetric初期化問題です。
さて、何らかのサーバーAがあったとして、それが更に他のサーバーBにRPCを送っているとします。サーバーBの方でホワイトボックスモニタリングをするのは当然として、サーバーA側でもサーバーBからのレスポンスを記録すると思います。というわけで、サーバーAでは以下のようなmetricsを吐くとします。
rpc_response{status=OK, service=B} 100
T0でこの状態だったとします。そしてT1(T0 + 1分)で
となってた場合、rpc_response{status=OK, service=B} 160
irate(rpc_response[5m])
=> {status=OK, service=B} 1
となります。そしてT2(T0+1分)でエラー発生、metrics
rpc_response{status=OK, service=B} 190
rpc_response{status=ERR, service=B} 60
となったとしたら
irate(rpc_response[5m])
=> {status=OK, service=B} 0.5
であり、ここにstatus=ERRが出てきません。これはirate()が最低でも2つのデータを必要とするからです。
じゃー、T3でどうなるかと。このエラーは突発的なものだったのでにstatus=ERRは変化がなかったとします。
rpc_response{status=OK, service=B} 250
rpc_response{status=ERR, service=B} 60
irate(rpc_response[5m])
=> {status=OK, service=B} 0.5
{status=ERR, service=B} 0
というわけで、irate() (rate())を使っている限り、このエラーはグラフにも表示されず、アラートも発生することはありません。
この問題の原因は「データ(カウンター)が存在しない != 値が 0」というところにあります。そこで、この問題の解決策は…
- もし取りうるstatusが最初から分かっているのなら、事前にrpc_responseカウンターを全てのstatusに対して0で初期化しておく。
- あきらめるw
- rate()の結果が存在しないけど、その元となるmetricが存在する場合には、その元となるmetricを直接使うようにPromQLをゴリゴリ書く
のいずれかです。番外として「Prometheusに手を入れて『rate()では、データが存在しない == 値が 0とみなす』」というのもありますが、これはprometheusの先祖であるborgmonがすでに通った茨の道、絶対におすすめしません。
なお、計算を簡単にするためにirate()を上では使ってましたが、「0で初期化されてないカウンター」問題はrate()でも一緒です。
ところで、bloggerのエディターはしょぼいですね。中の人も全然使ってないんじゃないのかな…
0 件のコメント:
コメントを投稿