參考:
https://www.prometheus.wang/ha/prometheus-local-storage.html
本地存儲
Prometheus 2.x 采用自定義的存儲格式將樣本數據保存在本地磁盤當中。如下所示,按照兩個小時為一個時間窗口,將兩小時內產生的數據存儲在一個塊(Block)中,每一個塊中包含該時間窗口內的所有樣本數據(chunks),元數據文件(meta.json)以及索引文件(index)。
t0 t1 t2 now
┌───────────┐ ┌───────────┐ ┌───────────┐
│ │ │ │ │ │ ┌────────────┐
│ │ │ │ │ mutable │ <─── write ──── ┤ Prometheus │
│ │ │ │ │ │ └────────────┘
└───────────┘ └───────────┘ └───────────┘ ^
└──────────────┴───────┬──────┘ │
│ query
│ │
merge ──────────────────────────────────┘
當前時間窗口內正在收集的樣本數據,Prometheus則會直接將數據保存在內存當中。為了確保此期間如果Prometheus發生崩潰或者重啟時能夠恢復數據,Prometheus啟動時會從寫入日志(WAL)進行重播,從而恢復數據。此期間如果通過API刪除時間序列,刪除記錄也會保存在單獨的邏輯文件當中(tombstone)。
在文件系統中這些塊保存在單獨的目錄當中,Prometheus保存塊數據的目錄結構如下所示:
./data
|- 01BKGV7JBM69T2G1BGBGM6KB12 # 塊
|- meta.json # 元數據
|- wal # 寫入日志
|- 000002
|- 000001
|- 01BKGTZQ1SYQJTR4PB43C8PD98 # 塊
|- meta.json #元數據
|- index # 索引文件
|- chunks # 樣本數據
|- 000001
|- tombstones # 邏輯數據
|- 01BKGTZQ1HHWHV8FBJXW1Y3W0K
|- meta.json
|- wal
|-000001
通過時間窗口的形式保存所有的樣本數據,可以明顯提高Prometheus的查詢效率,當查詢一段時間范圍內的所有樣本數據時,只需要簡單的從落在該范圍內的塊中查詢數據即可。
同時該存儲方式可以簡化歷史數據的刪除邏輯。只要一個塊的時間范圍落在了配置的保留范圍之外,直接丟棄該塊即可。
|
┌────────────┐ ┌────┼─────┐ ┌───────────┐ ┌───────────┐
│ 1 │ │ 2 | │ │ 3 │ │ 4 │ . . .
└────────────┘ └────┼─────┘ └───────────┘ └───────────┘
|
|
retention boundary
本地存儲配置

在一般情況下,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會對時間序列進行壓縮效率,減少時間序列的數量效果更明顯。
