夜鶯 v9 記錄規則(Recording Rule):把複雜高基數 PromQL 預聚合成新指標,讓告警和儀表板查詢從分鐘級降到秒級。
概述
記錄規則(Recording Rule) = 按固定頻率提前跑一段 PromQL,把結果寫成新指標回存,告警/儀表板後續查這個新指標即可,省掉每次重算的開銷。
側欄路徑:資料查詢 → 指標 → 記錄規則 Tab,URL /recording-rules。
為什麼需要它?複雜查詢(多 join、高基數 sum、histogram_quantile)每次執行都很重。如果:
- 同一個查詢被多個告警規則、多個儀表板反覆用;
- 查詢本身慢(幾秒甚至幾十秒);
- 長 range(
[1h]、[1d])的查詢,每分鐘告警判定時都要回算;
把它做成記錄規則,每分鐘(或你指定的頻率)預算一次,結果作為新指標存起來。後續告警/儀表板只查這個輕量新指標,毫秒級返回。
經典場景:
node:cpu:usage_pct=100 - (avg by (instance) (rate(cpu_idle[5m])) * 100),給告警和大盤共用;service:http_latency:p99_5m=histogram_quantile(0.99, sum by (service, le) (rate(http_duration_bucket[5m]))),所有告警都基於這個;business:order_success_rate:1m= 業務指標,跨多個資料來源 join 後歸一化。
新建 / 編輯記錄規則
表單分四塊:
① 基礎設定
| 欄位 | 必填 | 說明 |
|---|---|---|
| 業務組 | 是 | 規則歸屬,做權限隔離 |
| 備註 | 否 | 簡短描述這條規則的用途,方便團隊協作 |
| 附加標籤 | 否 | key=value 格式,寫入新指標的額外標籤。例如附加 team=infra,方便後續過濾 |
② 指標設定:定義產出什麼新指標
每個「指標設定」區塊產出一條新指標。可以加多個區塊,一條規則同時寫多個指標。
| 欄位 | 必填 | 說明 |
|---|---|---|
| 回寫資料來源 開關 | 預設開 | 關掉後規則只在記憶體裡跑(用於除錯),不實際產出指標 |
| 查詢條件 A / B / … | 至少 1 個 | 定義一個或多個 PromQL,每個有自己的資料來源類型 + 資料來源 + 查詢語句 |
| 新指標名稱 | 是 | 產出指標的 metric name,Prometheus 命名約定推薦:<level>:<metric>:<operations>,如 node:cpu:usage_pct |
| 計算表達式 | 是 | 引用前面查詢條件的結果做合成。預設 $A 即直接用 A 的結果;可以寫 $A / $B * 100 這種二次計算 |
| 目標時序源 | 是 | 新指標寫到哪個 Prometheus 相容資料來源 |
③ 多查詢 + 跨資料來源
「新增指標設定」按鈕可以再加一塊,一條記錄規則同時產出多個指標 — 適合「一次抓資料,產出多個衍生指標」的場景。
如果在指標設定裡加多個查詢條件(A、B、C),還能做跨資料來源 join:A 來自 Prometheus、B 來自 MySQL,計算表達式 $A * $B 把兩邊資料相乘 — 不過這種用法謹慎,效能不一定比直接聯邦更好。
④ 其他設定
| 欄位 | 說明 |
|---|---|
| 執行頻率 | cron 表達式,預設 @every 15s。不要比原始指標的抓取頻率短 — 比如指標本身 15s 一個點,記錄規則 5s 跑一次沒意義。常用值:@every 1m / @every 15s |
實操:把慢告警查詢替換成記錄規則
舉個常見例子。原本一條告警查:
histogram_quantile(0.99, sum by (service, le) (rate(http_duration_seconds_bucket[5m]))) > 1
這個查詢基數高 + range 長,告警引擎每 30s 跑一次很重。改造步驟:
- 來
/recording-rules/add,新建一條規則; - 新指標名稱:
service:http_latency:p99_5m; - 查詢條件 A:填上面那串 PromQL(不帶
> 1閾值); - 計算表達式:
$A; - 目標時序源:選告警引擎能查到的資料來源;
- 執行頻率:
@every 30s(和告警判定同頻); - 儲存。
新建完後稍等一會(夠跑一次),去 即時查詢 驗證 service:http_latency:p99_5m{} 有資料。
最後回告警規則裡把 PromQL 改成 service:http_latency:p99_5m > 1 — 查詢直接從一個輕量指標裡讀,告警判定毫秒級搞定。
常見問題
Q1:記錄規則配好了但是查不到新指標?
A:按順序排查:
- 等夠一個執行週期(預設 15s,最長 1m);
- 「資料預覽」按鈕看 PromQL 是否能查出原始資料 — 查不出說明源 PromQL 本身有問題;
- 檢查「目標時序源」是不是支援 remote_write(絕大多數 Prometheus 相容資料來源都支援,但 PromQL 唯讀的閘道可能不支援);
- 看夜鶯 Server 日誌有沒有
recording rule eval failed之類的錯誤; - 檢查記錄規則的「啟用」開關是否打開。
Q2:記錄規則的執行頻率怎麼選最合適?
A:建議和告警判定頻率對齊,且不短於原始指標抓取頻率:
- 原始抓取 15s + 告警判定 30s → 記錄規則
@every 30s最佳; - 抓取 1m + 告警判定 1m → 記錄規則
@every 1m; - 想做秒級告警?得先把原始指標抓取頻率也提到秒級,否則記錄規則跑再快也是相同的資料點。
Q3:能不能寫一條記錄規則用於歷史回填?
A:不能。記錄規則只對「未來的資料」生效 — 從啟用那一刻開始按頻率產出。歷史區間內沒有新指標。如果需要回填,思路是:
- 在原始資料來源上用 PromQL 直接查(速度慢點也認了);
- 或用 VictoriaMetrics 的 vmalert 離線模式 跑歷史回填。
Q4:高基數指標做記錄規則會不會反而更慢?
A:會 — 如果做錯了。記錄規則要主動降基數:
- 用
sum by (維度子集):把上百個標籤收斂到只保留關鍵的幾個; - 別保留
instance/pod這種瞬變標籤(除非業務必需); - 輸出的新指標 series 數應該比輸入少 1-2 個數量級。
否則記錄規則只是把「查詢慢」變成「寫入慢 + 查詢稍快」。