在講述什麼是Recording Rules以前,讓咱們想一想是否咱們在使用Pronetheus過程當中,遇到相似的場景:隨着時間的推移,Prometheus中存儲的指標數量增長了,查詢的頻次也增長了,在作一些複雜的查詢的時候,常常會由於超時而致使Grafana中的圖沒法渲染。更壞的狀況是,在你選擇了較長時間維度的狀況下,Prometheus 會OOM。node
此時咱們都能想到預聚合這個概念。其實Recording Rules就是 Prometheus的預聚合。官方對於Recording Rules的定義以下:lua
一致的記錄規則命名方案使一目瞭然的解釋規則的含義更加容易,而且經過使錯誤或無心義的計算脫穎而出來避免錯誤。
定義老是讓人云裏霧裏,不知因此。因此咱們拿一個示例來講明。spa
假如你用Prometheus監控Kubernetes,那麼你對下面的兩個指標應該不會陌生,container_cpu_usage_seconds_total
和container_memory_usage_bytes
),分別表示容器的CPU和內存使用。code
當咱們須要監控Kubernetes node 節點的CPU和內存的實際利用率時,咱們的實現方案以下:內存
經過使用滑動窗口將container_cpu_usage_seconds_total總數除以kube_node_status_allocatable_cpu_cores總數得出的CPU利用率:io
sum(rate(container_cpu_usage_seconds_total[5m])) / avg_over_time(sum(kube_node_status_allocatable_cpu_cores)[5m:5m]) Load time: 15723ms
經過使用滑動窗口將container_memory_usage_bytes總數除以kube_node_status_allocatable_memory_bytes總數來計算內存利用率:table
avg_over_time(sum(container_memory_usage_bytes)[15m:15m]) / avg_over_time(sum(kube_node_status_allocatable_memory_bytes)[5m:5m]) Load time: 18656ms
當容器比較少的時候,固然這沒有什麼問題。可是當咱們運行了成千上萬個容器的時候,這種查詢就比較耗時了。容器
這個時候須要Recording Rules出場了。它容許你基於其餘時間序列建立自定義的元時間序列。監控
其實用過Prometheus Operator的話,會發現使用了大量的Recording Rules。渲染
groups: - name: k8s.rules rules: - expr: | sum(rate(container_cpu_usage_seconds_total{job="kubelet", image!="", container_name!=""}[5m])) by (namespace) record: namespace:container_cpu_usage_seconds_total:sum_rate - expr: | sum(container_memory_usage_bytes{job="kubelet", image!="", container_name!=""}) by (namespace) record: namespace:container_memory_usage_bytes:sum
如今,我能夠將查詢更改成以下所示:經過使用滑動窗口將container_cpu_usage_seconds_total總數除以kube_node_status_allocatable_cpu_cores總數得出的CPU利用率:
sum(namespace:container_cpu_usage_seconds_total:sum_rate) / avg_over_time(sum(kube_node_status_allocatable_cpu_cores)[5m:5m]) Load time: 1077ms
比以前的查詢快了14倍。
經過使用滑動窗口將container_memory_usage_bytes總數除以kube_node_status_allocatable_memory_bytes總數來計算內存利用率:
sum(namespace:container_memory_usage_bytes:sum) / avg_over_time(sum(kube_node_status_allocatable_memory_bytes)[5m:5m]) Load time: 677ms
比以前的查詢快了27倍。
顧名思義,Recording Rules是在rule_files定義。
每個規則文件經過如下格式進行定義:
groups: [ - <rule_group> ]
示例:
- record: instance_path:request_latency_seconds_count:rate5m expr: rate(request_latency_seconds_count{job="myjob"}[5m]) - record: instance_path:request_latency_seconds_sum:rate5m expr: rate(request_latency_seconds_sum{job="myjob"}[5m])
這些規則文件的計算頻率與告警規則計算頻率一致,都經過global.evaluation_interval定義:
global: [ evaluation_interval: <duration> | default = 1m ]
Recording Rules 其實就是拿空間換時間的典型,週期性經過複雜的查詢,造成一個新的自定義metric。此時,咱們就能夠直接查詢這個metric。由此帶來的好處是,查詢快速,由於不涉及到複雜的運算和不須要讀取海量的點。