Prometheus源码:存储指标

基于release-3.0

存储指标结构

// File Path: scrape/scrape
type scrapeCache struct {
// 被缓存的批次数
iter uint64 // Current scrape iteration.

// 上次成功时有多少序列和元数据条目。
// How many series and metadata entries there were at the last success.
successfulCount int

// Parsed string to an entry with information about the actual label set
// and its storage reference.
series map[string]*cacheEntry

// Cache of dropped metric strings and their iteration. The iteration must
// be a pointer so we can update it.
// 缓存不合法指标
droppedSeries map[string]*uint64

// seriesCur and seriesPrev store the labels of series that were seen
// in the current and previous scrape.
// We hold two maps and swap them out to save allocations.
seriesCur map[uint64]labels.Labels
seriesPrev map[uint64]labels.Labels

metaMtx sync.Mutex
metadata map[string]*metaEntry

metrics *scrapeMetrics
}

核心方法:

  • func (c *scrapeCache) iterDone(flushCache bool) : 用于scrapeCache缓存整理
  • func (c *scrapeCache) get(met []byte) (*cacheEntry, bool, bool):根据指标信息met,活去cacheEntry结构
  • func (c *scrapeCache) addRef(met []byte, ref storage.SeriesRef, lset labels.Labels, hash uint64):根据指标信息增加cacheEntry节点
  • func (c *scrapeCache) addDropped(met []byte) :添加无效指标信息到dropped列表
  • func (c *scrapeCache) getDropped(met []byte) bool:判断met是否为无效指标
  • func (c *scrapeCache) trackStaleness(hash uint64, lset labels.Labels) :添加不带时间戳的指标到seriesCur列表
  • func (c *scrapeCache) forEachStale(f func(labels.Labels) bool):查找过期指标

流程

  1. 在scrapeLoop.append中,先获取到指标存储器(app)和指标解析器(p),从p中循环活去指标met并通过sl.cache.getDropped方法判断met是否是不合法指标,如果不合法指标就丢弃,然后根据met在sl.cache.get(entries)中查找cacheEntry
  2. 如果查找到对应的cacheEntry,就调用app.AddFast方法进行指标存储
  3. 如果没有查找到对应的 cacheEntry,就调用 app.Add 方法进行 指标存储
  4. 在进行指标存储操作前,会根据在 prometheus.yml 中配 置的 HonorLabels、MetricRelabelConfigs 规则,对指标的 label 进行重置,然后对指标的合法性进行校验,校验方式为判断指标的 label是否为空。如果校验结果不合法,就将 met添加到scrapeCache 的dropped列表中,以供下一次指标存储前匹配校验,最后将指标通过 sl.cache.addRef 方 法 缓 存 到 scrapeCache 的 entries 列 表 。
  5. sl.cache.addRef方法主要用于将指标信息构造为cacheEntry结构。 被存储的指标还分为自带时间戳与不带时间戳两种。自带时间戳 的指标的存储按照上述流程处理。而不带时间戳的指标的存储,则将 系 统 的 当 前 时 间 作 为 指 标 的 时 间 , 并 且 会 将 指 标 通 过 sl.cache.trackStaleness方法缓存到scrapeCache的seriesCur列表 中。 对过期指标的处理通过调用 sl.cache.forEachStale方法完成。
  6. 在 forEachStale方法中先遍历 scrapeCache 结构中的 seriesPrev, 并判断 seriesPrev 中的指标是否存在于seriesCur中,如果不存在, 就表示该指标为过期指标,并将过期指标的值设置为StaleNaN 后进行 存储,如果存在就不做处理。在 seriesPrev 中缓存了上次存储的指 标中不带时间戳的指标