在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中的所有label名称
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结构体来窥探下创建本地tsdb存储时,我们可以修改哪些配置:
MinBlockDuration
MaxBlockDuration
WalSegmentSize
RetentionDuration
MaxBytes
NoLockfile
AllowOverlappingBlocks
WALCompression