在cmd/main.go下包含了prometheus啟動時初始化的過程,這里基本就包括了prometheus各個重要組件的初始化過程。
prom采用 alecthomas/kingpin.v2 獲取參數,prom的集群工具thanos也使用類似的初始化邏輯。
在main.go大約300多行(不排除之后版本變化),有存儲組件的初始化
var (
localStorage = &tsdb.ReadyStorage{}
remoteStorage = remote.NewStorage(...)
fanoutStorage = storage.NewFanout(..., localStorage, remoteStorage)
)
fanoutStorage是本地存儲和遠程存儲的讀寫代理器,這個NewFanout的參數為 (logger log.Logger, primary Storage, secondaries ...Storage),也就是說,這個代理器其實是可以傳入多個遠程存儲對象的。
基礎數據接口
這個Storage存儲接口包含以下:
Close() error 關閉存儲以及其下的所有resource
Appender() (Appender, error)
StartTime() (int64, error) 返回存儲中最早的時間戳
Queryable 這個接口中實現一個方法 Querier(xxx) 返回存儲的一個Querier接口
上面Appender返回返回的Appender也是一個接口,定義了以下方法:
Add(l labels.Labels, t int64, v float64) (uint64, error)
AddFast(l labels.Labels, ref uint64, t int64, v float64) error
// 這里的commit做了兩件事:提交所有已存儲的樣本(collected samples),清空batch中的數據點
Commit() error
Rollback() error
其實這個appender的用途就是批量添加時序數據點,不過既然是批量操作,那么就不免有應用意外終止導致數據點丟失的可能
而Querier接口定義了以下方法:
Select(*SelectParams, ... *labels.Matcher) (SeriesSet, Warnings, error)
根據你給定的搜索參數(selectParam,如起止時間、步進、聚合函數)然后返回一組時序數據(這個數據的樣式就是調用prom的query http API)
LabelValues(name string) ([]string, Warnings, error)
該方法返回一個label可能的所有值
LabelNames() ([]string, Warnings, error)
按照排序返回存儲block中的所有l(wèi)abel名稱
Close() error 釋放資源(這里釋放的應該就是對應存儲的客戶端)
這里的Select方法返回的SeriesSet接口,包含以下方法:
Next() bool // 是否還有下一個數據點
At() Series
Err() error
這里的At()方法返回的Series接口,包含:
// 返回定義series的完整label,因為prom是支持模糊搜索的,那么這里的labels.Labels和你Select時輸入的Labels可能并不相同
Labels() labels.Labels
Iterator() SeriesIterator
SeriesIterator會將這條series上,符合你時間要求(select時是輸入了一個時間段)上的數據點全部進行迭代,包含以下方法:
Seek(t int64) bool
// 返回當前時間戳/數值對
At() (t int64, v float64)
Next() bool
Err() error
** prom中的Warnings 就是一組error,應是捕捉到的不影響核心功能的錯誤
存儲代理實現的方法
也就是初始化過程中,Storage.NewFanout返回的fanout對象指針,這會將prom代碼中產生的讀寫的操作代理到primary存儲和secondary存儲中。
fanout實現了以下方法:
StartTime() (int64, error)
遍歷調用所有存儲中的StartTime()方法,然后找出最早的那個時間戳。
Querier(ctx context.Context, mint , maxt int64)(Querier, error)
調用了所有存儲對象的Querier方法,一旦有一個存儲的Querier方法報錯,就直接返回錯誤。這里使用 NewMergeQuerier 實現了一個合并
本地存儲
在main.go中初始化的本地存儲是ReadyStorage對象,其由一個讀寫鎖和一個adapter對象指針組成,adapter由一個時間戳(起始時間) 一個tsdb.DB對象組成。
prometheus使用的本地tsdb存儲名為Gorilla,是一個快捷、可伸縮、內建的時序數據庫。
我們可以通過Option結構體來窺探下創(chuàng)建本地tsdb存儲時,我們可以修改哪些配置:
MinBlockDuration
MaxBlockDuration
WalSegmentSize
RetentionDuration
MaxBytes
NoLockfile
AllowOverlappingBlocks
WALCompression