儲存
Prometheus 包含一個本地磁碟時序資料庫,但也可以選擇與遠端儲存系統整合。
本地儲存
Prometheus 的本地時序資料庫以一種自定義且極其高效的格式將資料儲存在本地儲存中。
磁碟佈局
攝入的樣本按兩小時分為一個塊(Block)。每個塊由一個目錄組成,該目錄包含一個 chunks 子目錄(包含該時間視窗內的所有時序樣本)、一個元資料檔案(metadata)和一個索引檔案(index,用於將指標名稱和標籤對映到 chunks 目錄中的時序)。chunks 目錄中的樣本被組織成一個或多個段(segment)檔案,預設情況下每個檔案最大為 512 MB。當透過 API 刪除序列(series)時,刪除記錄將儲存在獨立的 tombstone 檔案中,而不是立即從 chunk 段中移除。
當前接收樣本的塊儲存在記憶體中,並未完全持久化。為了防止崩潰,它透過預寫日誌(WAL)進行保護,該日誌可以在 Prometheus 伺服器重啟時重新播放。預寫日誌檔案儲存在 wal 目錄中,每個段為 128MB。這些檔案包含尚未經過壓縮合並的原始資料,因此它們通常比普通塊檔案大得多。Prometheus 將至少保留三個預寫日誌檔案。高流量的伺服器可能會保留三個以上的 WAL 檔案,以便儲存至少兩個小時的原始資料。
Prometheus 伺服器的資料目錄看起來像下面這樣
./data
├── 01BKGV7JBM69T2G1BGBGM6KB12
│ └── meta.json
├── 01BKGTZQ1SYQJTR4PB43C8PD98
│ ├── chunks
│ │ └── 000001
│ ├── tombstones
│ ├── index
│ └── meta.json
├── 01BKGTZQ1HHWHV8FBJXW1Y3W0K
│ └── meta.json
├── 01BKGV7JC0RY8A6MACW02A2PJD
│ ├── chunks
│ │ └── 000001
│ ├── tombstones
│ ├── index
│ └── meta.json
├── chunks_head
│ └── 000001
└── wal
├── 000000002
└── checkpoint.00000001
└── 00000000
請注意,本地儲存的一個限制是它沒有叢集化或副本。因此,在面臨磁碟或節點故障時,它不能任意擴容,也無法保證高可用性,應該像對待其他單節點資料庫一樣進行管理。透過合理的架構設計,完全可以在本地儲存中保留數年的資料。
推薦使用快照(Snapshots)進行備份。在不使用快照的情況下進行備份可能會面臨丟失自上一個 TSDB 塊建立以來所記錄的資料的風險,這通常每兩小時發生一次,覆蓋最近三小時的樣本。在備份或恢復時排除 WAL 檔案(storage.tsdb.path 中的 chunks_head/、wal/ 和 wbl/ 目錄)無論如何都能確保備份的一致性,代價是丟失 WAL 檔案覆蓋的時間範圍。
或者,可以透過遠端讀/寫 API 使用外部儲存。由於這些系統在可靠性、效能和效率方面差異巨大,因此需要對它們進行仔細評估。
有關檔案格式的更多詳細資訊,請參閱 TSDB 格式 。
壓縮合並
最初的兩小時塊最終會在後臺被壓縮合併為更長的塊。
壓縮合並將建立更大的塊,其中包含跨度達保留時間 10% 或 31 天的資料(以較小者為準)。
運維方面
Prometheus 有幾個配置本地儲存的啟動引數(Flag)。最重要的包括
--storage.tsdb.path: Prometheus 寫入其資料庫的路徑。預設為data/。--storage.tsdb.retention.time: 樣本在儲存中保留的時間。如果既沒有設定此引數,也沒有設定storage.tsdb.retention.size,則保留時間預設為15d。支援的單位有:y, w, d, h, m, s, ms。--storage.tsdb.retention.size: 要保留的儲存塊的最大位元組數。最舊的資料將被首先刪除。預設為0或停用。支援的單位有:B, KB, MB, GB, TB, PB, EB。例如:"512MB"。基於 2 的冪,因此 1KB 為 1024B。為了滿足此保留策略,只有持久化的塊會被刪除,儘管 WAL 和記憶體對映(m-mapped)的 chunk 也會計算在總大小中。因此,對磁碟的最低要求是wal(WAL 和 Checkpoint)和chunks_head(記憶體對映的 Head chunk)目錄所佔用的峰值空間之和(每 2 小時達到一次峰值)。--storage.tsdb.wal-compression: 啟用預寫日誌(WAL)的壓縮。根據您的資料,可以預期 WAL 大小會減半,而 CPU 額外負載極低。此引數在 2.11.0 版本中引入,並在 2.20.0 版本中預設啟用。請注意,一旦啟用,如果將 Prometheus 降級到 2.11.0 以下的版本,將需要刪除 WAL。
Prometheus 平均每個樣本僅儲存 1-2 個位元組。因此,要規劃 Prometheus 伺服器的容量,可以使用以下粗略公式
needed_disk_space = retention_time_seconds * ingested_samples_per_second * bytes_per_sample
要降低樣本攝入速率,您可以減少抓取的時序數量(減少目標或減少每個目標的時序數量),或者增加抓取間隔。然而,由於同一時序內樣本的壓縮效果,減少時序數量通常會更加有效。
如果您的本地儲存損壞到 Prometheus 無法啟動的程度,建議備份儲存目錄並從備份中恢復受損的塊目錄。如果您沒有備份,最後的手段是刪除損壞的檔案。例如,您可以嘗試刪除單個塊目錄或預寫日誌(WAL)檔案。請注意,這意味著會丟失這些塊或 WAL 所覆蓋的時間範圍內的資料。
注意Prometheus 的本地儲存不支援非 POSIX 相容的檔案系統,因為可能會發生無法恢復的損壞。不支援 NFS 檔案系統(包括 AWS 的 EFS)。NFS 本可以是 POSIX 相容的,但大多數實現並非如此。為了保證可靠性,強烈建議使用本地檔案系統。
如果同時指定了時間和大小保留策略,則以先觸發的為準。
過期塊的清理在後臺進行。刪除過期塊可能需要長達兩個小時。塊必須完全過期後才會被移除。
合理規劃保留大小
如果您正在使用 storage.tsdb.retention.size 來設定大小限制,您需要考慮該值相對於您為 Prometheus 分配的儲存空間的合理大小。降低保留大小以提供緩衝區是明智的,這樣可以確保在為 Prometheus 分配的儲存空間填滿之前刪除較舊的條目。
目前,我們建議將保留大小最多設定為分配給 Prometheus 磁碟空間的 80-85%。這增加了在達到任何磁碟限制之前刪除較舊條目的可能性。
遠端儲存整合
Prometheus 的本地儲存受限於單節點的擴充套件性和可靠性。Prometheus 並沒有試圖在自身內部解決叢集化儲存的問題,而是提供了一套介面,允許與遠端儲存系統整合。
概述
Prometheus 透過以下四種方式與遠端儲存系統整合
- Prometheus 可以將攝入的樣本以 遠端寫入(Remote Write)格式 寫入到遠端 URL。
- Prometheus 可以從其他客戶端以 遠端寫入(Remote Write)格式 接收樣本。
- Prometheus 可以從遠端 URL 以 遠端讀取(Remote Read)格式 讀取(回讀)樣本資料。
- Prometheus 可以將客戶端請求的樣本資料以 遠端讀取(Remote Read)格式 返回。

遠端讀寫協議都在 HTTP 上使用經 snappy 壓縮的 Protocol Buffer 編碼。讀取協議目前尚未被視為穩定的 API。
寫入協議包含 1.0 版本的穩定規範 和 2.0 版本的實驗性規範,Prometheus 伺服器均支援這兩者。
有關在 Prometheus 中作為客戶端配置遠端儲存整合的詳細資訊,請參閱 Prometheus 配置文件中的 遠端寫入(remote write) 和 遠端讀取(remote read) 部分。
請注意,在讀取路徑上,Prometheus 僅從遠端端獲取一組標籤選擇器和時間範圍的原始時序資料。對原始資料的所有 PromQL 評估仍發生在 Prometheus 自身中。這意味著遠端讀取查詢存在一定的擴充套件性限制,因為所有必要的資料必須首先載入到進行查詢的 Prometheus 伺服器中,然後在那裡進行處理。然而,目前對 PromQL 的完全分散式評估支援被認為是不可行的。
Prometheus 也提供這兩個協議的服務。內建的遠端寫入接收器可以透過設定 --web.enable-remote-write-receiver 命令列引數來啟用。啟用後,遠端寫入接收器端點為 /api/v1/write。遠端讀取端點可在 /api/v1/read 上訪問。
現有整合
要了解有關與遠端儲存系統現有整合的更多資訊,請參閱 整合文件。
從 OpenMetrics 格式回填資料
概述
如果使用者想要將 OpenMetrics 格式的資料匯入 TSDB 中建立資料塊,可以透過資料回填(backfilling)來實現。然而,他們應該小心並注意,回填最近 3 小時內的資料(當前的 head 塊)是不安全的,因為這個時間範圍可能會與 Prometheus 仍在修改的當前 head 塊重疊。回填將建立新的 TSDB 塊,每個塊包含兩小時的指標資料。這限制了建立塊時的記憶體需求。兩小時塊壓縮為更大塊的工作隨後由 Prometheus 伺服器自身完成。
一個典型的用例是將指標資料從其他監控系統或時序資料庫遷移到 Prometheus。為此,使用者必須首先將源資料轉換為 OpenMetrics 格式,這是下文所述回填過程的輸入格式。
請注意,由於無法在 OpenMetrics 格式中表示,此過程不支援原生直方圖和陳舊性標記。
用法
資料回填可以透過 promtool 命令列進行。promtool 將把資料塊寫入一個目錄中。預設情況下,此輸出目錄為 ./data/,您可以透過在子命令中使用所需輸出目錄的名稱作為可選引數來更改它。
promtool tsdb create-blocks-from openmetrics <input file> [<output directory>]
建立塊後,將其移動到 Prometheus 的資料目錄中。如果與 Prometheus 中現有的塊存在重疊,則對於 v2.38 及以下版本的 Prometheus,需要設定 --storage.tsdb.allow-overlapping-blocks 引數。請注意,任何回填的資料都受您為 Prometheus 伺服器配置的保留策略(按時間或大小)的約束。
更長的塊持續時間
預設情況下,promtool 將對塊使用預設的塊持續時間(2h);這種行為是最通用且正確的。然而,當在很長的時間範圍內回填資料時,使用更大的塊持續時間值可能會更有利,以便更快地進行回填,並防止 TSDB 隨後進行額外的壓縮合並。
--max-block-duration 引數允許使用者配置塊的最大持續時間。回填工具將選擇一個不大於此值的合適塊持續時間。
雖然較大的塊可以提高回填大型資料集的效能,但也存在缺點。在基於時間的保留策略下,即使(可能很大的)塊中只有單個樣本仍在保留策略範圍內,也必須保留整個塊。相反,在基於大小的保留策略下,即使 TSDB 僅稍微超出大小限制,也會刪除整個塊。
因此,透過選擇較大的塊持續時間來減少回填生成的塊數量必須謹慎進行,不建議在任何生產例項中使用。
記錄規則的資料回填
概述
當建立新的記錄規則時,該規則沒有歷史資料。記錄規則資料僅從建立時間開始存在。promtool 使得建立歷史記錄規則資料成為可能。
用法
要檢視所有選項,請使用:$ promtool tsdb create-blocks-from rules --help。
使用示例
$ promtool tsdb create-blocks-from rules \
--start 1617079873 \
--end 1617097873 \
--url http://mypromserver.com:9090 \
rules.yaml rules2.yaml
提供的記錄規則檔案應該是一個正常的 Prometheus 規則檔案。
promtool tsdb create-blocks-from rules 命令的輸出是一個目錄,其中包含記錄規則檔案中所有規則的歷史規則資料塊。預設情況下,輸出目錄為 data/。為了使用這些新的塊資料,必須將這些塊移動到執行中的 Prometheus 例項資料目錄 storage.tsdb.path 中(對於 v2.38 及以下版本的 Prometheus,必須啟用 --storage.tsdb.allow-overlapping-blocks 引數)。移動後,在下一次執行壓縮合並時,新的塊將與現有的塊合併。
侷限性
- 如果您多次執行規則回填且開始/結束時間存在重疊,則每次執行規則回填時都會建立包含相同資料的塊。
- 記錄規則檔案中的所有規則都將被評估。
- 如果在記錄規則檔案中設定了
interval(時間間隔),它將優先於規則回填命令中的eval-interval引數。 - 目前,如果記錄規則檔案中包含告警,它們會被忽略。
- 同一組中的規則無法看到之前規則的結果。這意味著不支援引用其他正在回填的規則的規則。一種解決方法是多次進行回填,首先建立依賴的資料(並將依賴的資料移動到 Prometheus 伺服器的資料目錄中,以便可以透過 Prometheus API 訪問它)。