- 一、整體介紹
- 二、block
- 2.1 head block
- 三、WAL(Write-ahead logging, 預寫日志)
- 3.1 數據流向
- 四、和存儲相關的啟動參數
- 五、總結
一、整體介紹
Prometheus 2.x 采用自定義的存儲格式將樣本數據保存在本地磁盤當中。如下所示,按照兩個小時(最少時間)為一個時間窗口,將兩小時內產生的數據存儲在一個塊(Block)中,每一個塊中包含該時間窗口內的所有樣本數據(chunks),元數據文件(meta.json)以及索引文件(index)。
[mingming.chen@m162p65 data]$ tree . ├── 01E2MA5GDWMP69GVBVY1W5AF1X │ ├── chunks # 保存壓縮后的時序數據,每個chunks大小為512M,超過會生成新的chunks │ │ └── 000001 │ ├── index # chunks中的偏移位置 │ ├── meta.json # 記錄block塊元信息,比如 樣本的起始時間、chunks數量和數據量大小等 │ └── tombstones # 通過API方式對數據進行軟刪除,將刪除記錄存儲在此處(API的刪除方式,並不是立即將數據從chunks文件中移除) ├── 01E2MH175FV0JFB7EGCRZCX8NF │ ├── chunks │ │ └── 000001 │ ├── index │ ├── meta.json │ └── tombstones ├── 01E2MQWYDFQAXXPB3M1HK6T20A │ ├── chunks │ │ └── 000001 │ ├── index │ ├── meta.json │ └── tombstones ├── lock ├── queries.active └── wal #防止數據丟失(數據收集上來暫時是存放在內存中,wal記錄了這些信息) ├── 00000366 #每個數據段最大為128M,存儲默認存儲兩個小時的數據量。 ├── 00000367 ├── 00000368 ├── 00000369 └── checkpoint.000365 └── 00000000 |
二、block
TSDB將存儲的監控數據按照時間分成多個block存儲,默認最小的block保存時間為2h,后台程序還會將小塊合並成大塊,減少內存中block的數量,便於索引查找數據,可以通過meta.json查看,可以看到01E2MA5GDWMP69GVBVY1W5AF1X被壓縮1次,source有3個block,那么2*3=6小時的數據量。
關於block壓縮:
- 最初的兩個小時的塊最終會在后台壓縮為更長時間的塊;
- 壓縮的最大時間塊為數據保留時間的10%或者31天,取兩者的較小者。
2.1 head block
1.head block中的數據是被存儲在內存中的並且可以被任意修改;
2.head block和后續的block初始設定保存2h數據,當head block超過3h時,會被拆分為2h+1h,2h block會變成只讀塊寫入磁盤.(通過觀察服務器上prometheus存儲目錄,每次壓縮合並小塊時間都比塊內部時間多三個小時,為head block),如下所示:
三、WAL(Write-ahead logging, 預寫日志)

3.1 數據流向
prometheus將周期性采集到的數據通過Add接口添加到head block,但是這些數據暫時沒有持久化,TSDB通過WAL將數據保存到磁盤上(保存的數據沒有壓縮,占用內存較大),當出現宕機,啟動多協程讀取WAL,恢復數據。
四、和存儲相關的啟動參數
--storage.tsdb.path: This determines where Prometheus writes its database. Defaults to data/. --storage.tsdb.retention.time: This determines when to remove old data. Defaults to 15d. Overrides storage.tsdb.retention if this flag is set to anything other than default. --storage.tsdb.retention.size: [EXPERIMENTAL] This determines the maximum number of bytes that storage blocks can use (note that this does not include the WAL size, which can be substantial). The oldest data will be removed first. Defaults to 0 or disabled. This flag is experimental and can be changed in future releases. Units supported: KB, MB, GB, PB. Ex: "512MB" --storage.tsdb.retention: This flag has been deprecated in favour of storage.tsdb.retention.time. --storage.tsdb.wal-compression: This flag enables compression of the write-ahead log (WAL). Depending on your data, you can expect the WAL size to be halved with little extra cpu load. Note that if you enable this flag and subsequently downgrade Prometheus to a version below 2.11.0 you will need to delete your WAL as it will be unreadable. |
PS: 以上有兩個參數storage.tsdb.retention.size和storage.tsdb.retention.time,兩個同時設置時,兩者無優先級,誰先觸發就執行刪除操作。(其它啟動參數參考promethes#promethes 第五章節啟動參數部分)
五、總結
需要解決的幾個問題:
1.遠程存儲節點長時間掛掉(默認blocK大小為2小時,實際大於六小時,prometheus2.15經測試驗證非官方文檔說的兩個小時),刷盤到prometheus的數據庫中的數據還能不能同步到遠程?
2.WAL的緩存數據的時間可不可以調整?
解答:
1.根據以上內容和3.遠程寫參數優化可知,prometheus本地存儲和遠程存儲並無影響。因為遠程存儲是通過將WAL中的數據緩存到多個內存隊列(shards)中,然后寫到遠程存儲設備,其直接與WAL打交道。而prometheus只是用WAL來防止數據丟失,其存儲的一系列動作都與WAL沒關系。所以當內存中緩存的數據達到刷盤的閾值,WAL中沒有寫到遠程存儲的數據就會丟失,當重新啟動遠程存儲服務,原來那部分沒有寫入遠程存儲服務的數據已經丟失,只能從最新的數據開始寫入遠程存儲,這部分可參考3.遠程寫參數優化2.2部分結論。
2. 可以調整,准確來說是間接調整。wal保留數據的長短與prometheus最小壓縮block大小有關系,由於wal中至少保留當前時間正在寫入的文件之外的三個文件(每個文件保存一個block大小的數據量),所以當增大block大小的時候就會相應的增大wal保存的數據量,但是,block的大小調整會直接影響內存的使用,需要根據現有的環境進行相應的調優。
如下圖所示,當我設置--storage.tsdb.min-block-duration=4h(prometheus的啟動參數)時,wal中當前保留的文件(存在的數據時間范圍:2020.03.20 20:00:00–2020.03.21 13.52),其中每個文件保留4個小時的數據量。