PrometheusのRemoteWriteがんばり過ぎ問題と最近の関連パラメータ更新について

SampleAgeLimitというのがmainにマージされたのを観測したのでちょっと歴史を含めてメモしておくという雑記事です。

三行

  • 1) 2.11.0 / 2019-07-09 MaxRetriesが削除された
  • 2) 2.32.0 / 2021-12-09 MaxBackoffが100msから5secに変更
  • 3) xxx / 2024-01-05 SampleAgeLimitが追加されmainにマージされた(デフォルトは無効)

2年おきくらいになにがしか更新がある

RemoteWriteがんばり過ぎ問題

プロダクション環境の信頼性を損ねず観測する技術 - Speaker Deck

こういうの

  • PrometheusのRemoteWriteはExponential Backoffなリトライをする
  • しかしMaxBackoffに到達するとそこでひたすらRetryを繰り返す
  • WALは2h程度で削除されるのでいちおう無限に繰り返されるわけではない(という理解
  • 加えて、(RemoteWrite先が完全に死んでいれば行わないが)sampleの受け取りに対して書き込みが遅いとShardの数を増やして一度にRemoteWriteできる量を増やそうとする
  • しかしRemoteWrite先は古いsampleをいつまでも受け取らず大抵の場合はdropしてしまうので(例えば2h程度書き込み先が半死状態で、復旧したような場合)、ネットワーク帯域を最大限に使って大量のRemoteWriteを試みても、無駄になってしまう上に帯域を逼迫して障害を起こすことさえある

ということで

一周回ってSampleAgeLimit(再送するサンプルをいつまで保持するかを決定するパラメータ)が追加されたようです

個人的な雑感

  • 1)のMaxRetriesはたしか3回とかだったので、WALの話はあるにせよ、せっかくExponential Backoff実装しているのに100msが上限というのはやはり無茶な設定というか意味がなかったよなあと思う、SYNの再送でも秒単位だというのに、送信失敗した相手に対して秒間10回リトライするというのはやはりやりすぎだと思う
  • MaxBackoffが伸びたので今の環境はいくぶん再送まわりはましになっているがそれでも5秒でリトライは割と高頻度だと思う、どうせDropされてしまうのであれば(これはRemoteWrite先によるが)、SampleAgeLimitはかなり短く設定しておいてよいと思う、1分とかでもいいんじゃなかろうか
  • kube-prometheus-stackなんかで導入している環境は諸々デフォルトで設定されてくると思われるので、デフォルトが安全になってくれるといいなあという気分
  • メトリクスをあとで埋める方法も確かThanosあたりでなにか考えられてた気がするが、このあたりのコンセンサスが固まると双方幸せになりそう、新しいsampleのingestとbackfillみたいなものは分けて考えた方がいいんだろうなあ

ref

github.com

github.com

github.com

github.com

github.com