# Prometheusシリーズチャーン
## 定義
Prometheus において、時系列の識別子(ラベルセット)が短期間に大量に入れ替わる現象。新しいラベルセットが新しい時系列として登録される一方、旧時系列は「失活系列(stale series)」としてメモリ(HEAD)に残り続ける。Prometheus の通常 HEAD flush が 2 時間周期のため、その前に失活系列が累積してメモリ枯渇(OOM)を引き起こすリスクがある。
(Source: [[@2026__SREcon26Americas__Unlock High-Frequency Deployments without Blowing Up Prometheus]])
### 失活系列の発生源
- **ターゲット消滅**: プロセス停止・スケールダウン
- **計装変更**: ラベル追加・変更によって旧系列が別の系列として扱われる
- **Kubernetes ロールアウト**: Deployment では pod suffix が変わるため全系列が入れ替わる。StatefulSet では pod 名は同じでも IP 変更により instance ラベルが変わり、新系列として登録される
### Kubernetes 特有の増幅
```
my_metric{pod="my-pod-cf97d665c-wbzjs", ...} → my_metric{pod="my-pod-cf97d665c-vd5vf", ...}
```
pod 1 つあたり 100 メトリクスを持つとすると、再起動 1 回で Prometheus は 200 系列をメモリに保持することになる。高頻度デプロイでは 2 時間の flush より前に HEAD が圧迫される。
## 解決アプローチ
### stale-series compaction (Prometheus v3.10.0+)
閾値(`stale_series_compaction_threshold`)を設定し、失活系列比率がその値に達すると HEAD から失活系列をディスクの Block N へ先回りフラッシュする機能。
```yaml
storage:
tsdb:
stale_series_compaction_threshold: <0.0 to 1.0>
```
**トレードオフ**:
- ✅ メモリ削減・OOM 回避
- ❌ クエリ時に HEAD(メモリ) + Block N(ディスク)のマージが必要 → CPU 消費増・クエリレイテンシ増
- ❌ ルール数が多い環境ほどオーバーヘッドが大きい
**閾値選択指針** (Reddit 実験ベース):
計測: `prometheus_tsdb_head_stale_series{} / prometheus_tsdb_head_series{}`
| ピーク失活比率 | 推奨アクション |
|---|---|
| < 0.3 | 不要 |
| 0.3–0.5 | 様子見 |
| > 0.5 | 閾値を trial-and-error で決定 |
**注意**: この機能は「Prometheus を OOM から守る」保護目的。省メモリ目的には使わない。小規模 Prometheus や低チャーン環境ではオーバーヘッドが利点を上回る場合がある。
現状: **実験的(experimental)** / 既知バグ #18379 / 修正 ETA: Prometheus v3.12.0–v3.13.0
### スクレイプ時集約(materialized metrics)
ストレージ側で失活系列を捌く stale-series compaction とは異なり、**集約側**からラベルチャーンの影響を断つアプローチ。pod ラベルのようなインフラ由来ラベルをスクレイプ時に畳み込んで合算し、専用の集約済み系列として保存する。
- カウンタは累積型のため素の値を合算すると reset を跨いで過大評価される。値を delta(差分)化してから合算すれば安全に扱える
- delta を固定間隔(スクレイプ間隔)ごとに強制リセットする「ジグザグカウンタ」を作ると、レプリカ間で合意プロトコルなしに比較・重複排除・欠損補完が可能になる
- 本番実装で最大メトリクスの系列数を98%削減、クエリスループット88%減・レイテンシ80%減、平均誤差率0.15%を達成
(Source: [[@2026__RedditEng__Materialized Metrics in Prometheus]])。手法の詳細は [[マテリアライズドメトリクス]] を参照。
## 横断的知見
- Reddit のオブザーバビリティチームは、pod ラベルによる同一のシリーズチャーン問題に対して、時期の異なる2つの独立した打ち手を公表している。[[@2026__SREcon26Americas__Unlock High-Frequency Deployments without Blowing Up Prometheus]] の **stale-series compaction** は Prometheus の**ストレージ層**(HEAD からディスクへの先回りフラッシュ)で失活系列そのものの滞留を防ぐのに対し、[[@2026__RedditEng__Materialized Metrics in Prometheus]] の **マテリアライズドメトリクス** は**集約層**(スクレイプ時のジグザグカウンタ生成)でラベル自体を畳み込んで系列数を減らす。前者は「増えた系列をどう捌くか」、後者は「そもそも系列を増やさない/クエリに出さない」という異なるレイヤーの解法であり、両者は排他的でなく併用しうる(Source: [[@2026__SREcon26Americas__Unlock High-Frequency Deployments without Blowing Up Prometheus]], [[@2026__RedditEng__Materialized Metrics in Prometheus]])。
- 両手法とも「Prometheus の基本モデル(PromQL・ラベルセマンティクス)を変えずに実験的機能・フォークとして導入する」という共通の設計判断を取っている。recording rule のような公式にサポートされた回避策では規模に対する限界(継続的な背景負荷・タイムアウト)があるため、いずれも公式機能の外側で問題を解決した後にアップストリーム化を目指す点が共通する(Source: [[@2026__SREcon26Americas__Unlock High-Frequency Deployments without Blowing Up Prometheus]], [[@2026__RedditEng__Materialized Metrics in Prometheus]])。
## 未解決の問い
- stale-series compaction のバグ #18379 の具体的な影響範囲は何か(どのようなクエリパターンで問題が顕在化するか)
- Prometheus v3.12.0–v3.13.0 でバグ修正後の本番推奨閾値のベストプラクティスは確立されたか
- VictoriaMetrics・Mimir などの互換システムはシリーズチャーン問題にどのようにアプローチしているか
- StatefulSet で instance ラベルを付けない設計(pod ラベルのみ)にすれば StatefulSet 系のチャーンを防げるが、そのトレードオフは何か
- stale-series compaction とマテリアライズドメトリクスを同一 Prometheus インスタンスで併用した場合の相互作用・追加効果は検証されているか
- マテリアライズドメトリクスのアップストリーム化(OSS Prometheus への提案)は進んでいるか。stale-series compaction のような experimental フラグとして採用される可能性はあるか
## 関連
- [[Prometheus]] / [[Prometheus TSDB]] / [[マテリアライズドメトリクス]]
- [[@2026__SREcon26Americas__Unlock High-Frequency Deployments without Blowing Up Prometheus]]
- [[@2026__RedditEng__Materialized Metrics in Prometheus]]
- [[Ganesh Vernekar]] / [[Aleksandr Krivoshchekov]] / [[Walther Lee]] / [[Reddit]]
## 出典
- [[@2026__SREcon26Americas__Unlock High-Frequency Deployments without Blowing Up Prometheus]]: Ganesh Vernekar (Reddit), SREcon26 Americas 2026-03-26
- [[@2026__RedditEng__Materialized Metrics in Prometheus]]: Aleksandr Krivoshchekov・Walther Lee (Reddit)、2026年公開(推定)