簡介
Prometheus是SoundCloud公司開發的一站式監控告警平台,依賴少,功能齊全。
于2016年加入CNCF,廣泛用于 Kubernetes叢集的監控系統中,2018.8月成為繼K8S之後第二個畢業的項目。Prometheus作為CNCF生态圈中的重要一員,其活躍度僅次于 Kubernetes。
https://www.atatech.org/articles/131388#1 關鍵功能包括:
- 多元資料模型:metric,labels
- 靈活的查詢語言:PromQL, 在同一個查詢語句,可以對多個 metrics 進行乘法、加法、連接配接、取分數位等操作。
- 可獨立部署,拆箱即用,不依賴分布式存儲
- 通過Http pull的采集方式
- 通過push gateway來做push方式的相容
- 通過靜态配置或服務發現擷取監控項
- 支援圖表和dashboard等多種方式
https://www.atatech.org/articles/131388#2 核心元件:
- Prometheus Server: 采集和存儲時序資料
- client庫: 用于對接 Prometheus Server, 可以查詢和上報資料
- push gateway處理短暫任務:用于批量,短期的監控資料的彙總節點,主要用于業務資料彙報等
- 定制化的exporters,比如:HAProxy, StatsD,Graphite等等, 彙報機器資料的插件
- 告警管理:Prometheus 可以配置 rules,然後定時查詢資料,當條件觸發的時候,會将 alert 推送到配置的 Alertmanager
- 多種多樣的支援工具
https://www.atatech.org/articles/131388#3 優勢和劣勢:
- 同InfluxDB相比, 在場景方面:PTSDB 适合數值型的時序資料。不适合日志型時序資料和用于計費的名額統計。InfluxDB面向的是通用時序平台,包括日志監控等場景。而Prometheus更側重于名額方案。兩個系統之間有非常多的相似之處,包括采集,存儲,報警,展示等等
- Influxdata的組合有:telegraf+Influxdb+Kapacitor+Chronograf
- Promethues的組合有:exporter+prometheus server+AlertManager+Grafana
- 采集端prometheus主推拉的模式,同時通過push gateway支援推的模式。influxdata的采集工具telegraf則主打推的方式。
- 存儲方面二者在基本思想上相通,關鍵點上有差異包括:時間線的索引,亂序的處理等等。
- 資料模型上Influxdb支援多值模型,String類型等,更豐富一些。
- Kapacitor 是一個混合了 prometheus 的資料處理,存儲規則,報警規則以及告警通知功能的工具.而AlertManager進一步提供了分組,去重等等。
-
influxdb之前提供的cluster模式被移除了,現在隻保留了基于relay的高可用,叢集模式作為商業版本的特性釋出。prometheus提供了一種很有特色的cluster模式,通過多層次的proxy來聚合多個prometheus節點實作擴充。
同時開放了remote storage,是以二者又互相融合,Influxdb作為prometheus的遠端存儲。
- OpenTSDB 的資料模型與Prometheus幾乎相同,查詢語言上PromQL更簡潔,OpenTSDB功能更豐富。OpenTSDB依賴的是Hadoop生态,Prometheus成長于Kubernetes生态。
https://www.atatech.org/articles/131388#4 資料模型
- 采用單值模型, 資料模型的核心概念是metric,labels和samples.
- 格式:<metric name>{<label name>=<label value>, …}
- 例如:http_requests_total{method="POST",endpoint="/api/tracks"}。
- metric的命名具有業務含義,比如http_request_total.
- 名額的類型分為:Counter, Gauge,Historgram,Summary
- labels用于表示次元.Samples由時間戳和數值組成。
- jobs and instances
- Prometheus 會自動生成target和instances作為标簽
- job: api-server
- instance 1: 1.2.3.4:5670
- instance 2: 1.2.3.4:5671
- job: api-server
- Prometheus 會自動生成target和instances作為标簽
https://www.atatech.org/articles/131388#5 整體設計思路
Prometheus的整體技術架構可以分為幾個重要子產品:
- Main function:作為入口承擔着各個元件的啟動,連接配接,管理。以Actor-Like的模式協調元件的運作
- Configuration:配置項的解析,驗證,加載
- Scrape discovery manager:服務發現管理器同抓取伺服器通過同步channel通信,當配置改變時需要重新開機服務生效。
- Scrape manager:抓取名額并發送到存儲元件
- Storage:
- Fanout Storage:存儲的代理抽象層,屏蔽底層local storage和remote storage細節,samples向下雙寫,合并讀取。
- Remote Storage:Remote Storage建立了一個Queue管理器,基于負載輪流發送,讀取用戶端merge來自遠端的資料。
- Local Storage:基于本地磁盤的輕量級時序資料庫。
- PromQL engine:查詢表達式解析為抽象文法樹和可執行查詢,以Lazy Load的方式加載資料。
- Rule manager:告警規則管理
- Notifier:通知派發管理器
- Notifier discovery:通知服務發現
- Web UI and API:内嵌的管控界面,可運作查詢表達式解析,結果展示。
https://www.atatech.org/articles/131388#6 PTSDB概述
本文側重于Local Storage PTSDB的解析. PTSDB的核心包括:反向索引+視窗存儲Block。
資料的寫入按照兩個小時為一個時間視窗,将兩小時内産生的資料存儲在一個Head Block中,每一個塊中包含該時間視窗内的所有樣本資料(chunks),中繼資料檔案(meta.json)以及索引檔案(index)。
最新寫入資料儲存在記憶體block中, 2小時後寫入磁盤。背景線程把2小時的資料最終合并成更大的資料塊,一般的資料庫在固定一個記憶體大小後,系統的寫入和讀取性能會受限于這個配置的記憶體大小。而PTSDB的記憶體大小是由最小時間周期,采集周期以及時間線數量來決定的。
為防止記憶體資料丢失,實作wal機制。删除記錄在獨立的tombstone檔案中。
https://www.atatech.org/articles/131388#7 核心資料結構和存儲格式
PTSDB的核心資料結構是HeadAppender,Appender commit時wal日志編碼落盤,同時寫入head block中。
PTSDB本地存儲使用自定義的檔案結構。主要包含:WAL,中繼資料檔案,索引,chunks,tombstones
https://www.atatech.org/articles/131388#8 Write Ahead Log
WAL 有3種編碼格式:時間線,資料點,以及删除點。總體政策是基于檔案大小滾動,并且根據最小記憶體時間執行清除。
- 當日志寫入時,以segment為機關存儲,每個segment預設128M, 記錄數大小達到32KB頁時重新整理一次。當剩餘空間小于新的記錄數大小時,建立新的Segment。
- 當compation時WAL基于時間執行清除政策,小于記憶體中block的最小時間的wal日志會被删除。
- 重新開機時,首先打開最新的Segment,從日志中恢複加載資料到記憶體。
https://www.atatech.org/articles/131388#9 中繼資料檔案
meta.json檔案記錄了Chunks的具體資訊, 比如新的compactin chunk來自哪幾個小的chunk。 這個chunk的統計資訊,比如:最小最大時間範圍,時間線,資料點個數等等
compaction線程根據統計資訊判斷該blocks是否可以做compact:(maxTime-minTime)占整體壓縮時間範圍的50%, 删除的時間線數量占總體數量的5%。
https://www.atatech.org/articles/131388#10 索引
索引一部分先寫入Head Block中,随着compaction的觸發落盤。
索引采用的是倒排的方式,posting list裡面的id是局部自增的,作為reference id表示時間線。索引compact時分為6步完成索引的落盤:Symbols->Series->LabelIndex->Posting->OffsetTable->TOC
- Symbols存儲的是tagk, tagv按照字母序遞增的字元串表。比如__name__,go_gc_duration_seconds, instance, localhost:9090等等。字元串按照utf8統一編碼。
-
Series存儲了兩部分資訊,一部分是标簽鍵值對的符号表引用;另外一部分是時間線到資料檔案的索引,按照時間視窗切割存儲資料塊記錄的具體位置資訊,是以在查詢時可以快速跳過大量非查詢視窗的記錄資料,
為了節省空間,時間戳範圍和資料塊的位置資訊的存儲采用內插補點編碼。
- LabelIndex存儲标簽鍵以及每一個标簽鍵對應的所有标簽值,當然具體存儲的資料也是符号表裡面的引用值。
- Posting存儲倒排的每個label對所對應的posting refid
- OffsetTable加速查找做的一層映射,将這部分資料加載到記憶體。OffsetTable主要關聯了LabelIndex和Posting資料塊。TOC是各個資料塊部分的位置偏移量,如果沒有資料就可以跳過查找。
https://www.atatech.org/articles/131388#11 Chunks
資料點存放在chunks目錄下,每個data預設512M,資料的編碼方式支援XOR,chunk按照refid來索引,refid由segmentid和檔案内部偏移量兩個部分組成。
https://www.atatech.org/articles/131388#12 Tombstones
記錄删除通過mark的方式,資料的實體清除發生在compaction和reload的時候。以時間視窗為機關存儲被删除記錄的資訊。
https://www.atatech.org/articles/131388#13 查詢PromQL
Promethues的查詢語言是PromQL,文法解析AST,執行計劃和資料聚合是由PromQL完成,fanout子產品會向本地和遠端同時下發查詢資料,PTSDB負責本地資料的檢索。
PTSDB實作了定義的Adpator,包括Select, LabelNames, LabelValues和Querier.
PromQL定義了三類查詢:
瞬時資料 (Instant vector): 包含一組時序,每個時序隻有一個點,例如:http_requests_total
區間資料 (Range vector): 包含一組時序,每個時序有多個點,例:http_requests_total[5m]
純量資料 (Scalar): 純量隻有一個數字,沒有時序,例如:count(http_requests_total)
一些典型的查詢包括:
-
查詢目前所有資料
http_requests_total
select * from http_requests_total where timestamp between xxxx and xxxx
-
條件查詢
http_requests_total{code="200", handler="query"}
select * from http_requests_total where code="200" and handler="query" and timestamp between xxxx and xxxx
-
模糊查詢: code 為 2xx 的資料
http_requests_total{code~="20"}
select * from http_requests_total where code like "%20%" and timestamp between xxxx and xxxx
-
值過濾: value大于100
http_requests_total > 100
select * from http_requests_total where value > 100 and timestamp between xxxx and xxxx
-
範圍區間查詢: 過去 5 分鐘資料
http_requests_total[5m]
select * from http_requests_total where timestamp between xxxx-5m and xxxx
-
count 查詢: 統計目前記錄總數
count(http_requests_total)
select count(*) from http_requests_total where timestamp between xxxx and xxxx
-
sum 查詢:統計目前資料總值
sum(http_requests_total)
select sum(value) from http_requests_total where timestamp between xxxx and xxxx
-
top 查詢: 查詢最靠前的 3 個值
topk(3, http_requests_total)
select * from http_requests_total where timestamp between xxxx and xxxx order by value desc limit 3
-
irate查詢:速率查詢
irate(http_requests_total[5m])
select code, handler, instance, job, method, sum(value)/300 AS value from http_requests_total where timestamp between xxxx and xxxx group by code, handler, instance, job, method;
https://www.atatech.org/articles/131388#14 PTSDB關鍵技術點
https://www.atatech.org/articles/131388#15 亂序處理
PTSDB對于亂序的處理采用了最小時間視窗的方式,指定合法的最小時間戳,小于這一時間戳的資料會丢棄不再處理。
合法最小時間戳取決于目前head block裡面最早的時間戳和可存儲的chunk範圍。
這種對于資料行為的限定極大的簡化了設計的靈活性,對于compaction的高效處理以及資料完整性提供了基礎。
https://www.atatech.org/articles/131388#16 記憶體的管理
使用mmap讀取壓縮合并後的大檔案(不占用太多句柄),
建立程序虛拟位址和檔案偏移的映射關系,隻有在查詢讀取對應的位置時才将資料真正讀到實體記憶體。
繞過檔案系統page cache,減少了一次資料拷貝。
查詢結束後,對應記憶體由Linux系統根據記憶體壓力情況自動進行回收,在回收之前可用于下一次查詢命中。
是以使用mmap自動管理查詢所需的的記憶體緩存,具有管理簡單,處理高效的優勢。
https://www.atatech.org/articles/131388#17 Compaction
Compaction主要操作包括合并block、删除過期資料、重構chunk資料。
- 合并多個block成為更大的block,可以有效減少block個,當查詢覆寫的時間範圍較長時,避免需要合并很多block的查詢結果。
- 為提高删除效率,删除時序資料時,會記錄删除的位置,隻有block所有資料都需要删除時,才将block整個目錄删除。
-
block合并的大小也需要進行限制,避免保留了過多已删除空間(額外的空間占用)。
比較好的方法是根據資料保留時長,按百分比(如10%)計算block的最大時長, 當block的最小和最大時長超過2/3blok範圍時,執行compaction
https://www.atatech.org/articles/131388#18 快照
PTSDB提供了快照備份資料的功能,使用者通過admin/snapshot協定可以生成快照,快照資料存儲于data/snapshots/-目錄。
https://www.atatech.org/articles/131388#19 PTSDB最佳實踐
-
在一般情況下,Prometheus中存儲的每一個樣本大概占用1-2位元組大小。如果需要對Prometheus Server的本地磁盤空間做容量規劃時,可以通過以下公式計算:
needed_disk_space = retention_time_seconds * ingested_samples_per_second * bytes_per_sample
-
保留時間(retention_time_seconds)和樣本大小(bytes_per_sample)不變的情況下,如果想減少本地磁盤的容量需求,
隻能通過減少每秒擷取樣本數(ingested_samples_per_second)的方式。
是以有兩種手段,一是減少時間序列的數量,二是增加采集樣本的時間間隔。
考慮到Prometheus會對時間序列進行壓縮,是以減少時間序列的數量效果更明顯。
-
PTSDB的限制在于叢集和複制。是以當一個node當機時,會導緻一定視窗的資料丢失。
當然,如果業務要求的資料可靠性不是特别苛刻,本地盤也可以存儲幾年的持久化資料。
當PTSDB Corruption時,可以通過移除磁盤目錄或者某個時間視窗的目錄恢複。
- PTSDB的高可用,叢集和曆史資料的儲存可以借助于外部解決方案,不在本文讨論範圍。
-
曆史方案的局限性,PTSDB在早期采用的是單條時間線一個檔案的存儲方式。這中方案有非常多的弊端,比如:
Snapshot的刷盤壓力:定期清理檔案的負擔;低基數和長周期查詢查詢,需要打開大量檔案;時間線膨脹可能導緻inode耗盡。
https://www.atatech.org/articles/131388#20 PTSDB面臨的挑戰
在使用過程中,PTSDB也在某些方面遇到了一些問題,比如;
- Compaction對于IO, CPU, 以及Memory的影響
- 冷啟動後,預熱階段CPU和記憶體占用會上升
- 在高速寫入時會出現CPU的Spike等等
https://www.atatech.org/articles/131388#21 總結
PTSDB 作為K8S監控方案裡面存儲時序資料的實施标準,其在時序屆影響力和熱度都在逐漸上升。Alibaba TSDB目前已經支援通過Adapter的方式作為其remote storage的方案。
阿裡雲時序時空資料庫TSDB 1元購!立即體驗:
https://promotion.aliyun.com/ntms/act/tsdbtry.html?spm=5176.149792.775960.1.dd9e34e2zgsuEM&wh_ttid=pc