32.2 prometheus倒排索引统计功能

本节重点介绍 :

  • 获取采集端的高基数metrics的tsdb页面解析
  • tsdb统计函数Stats源码解读
    • 依赖倒排索引统计

获取采集端的高基数metrics

tsdb页面解析

  • Top 10 label names with value count: 标签中value最多的10个
  • Top 10 series count by metric names: metric_name匹配的series最多的10个
  • Top 10 label names with high memory usage: 标签消耗内存最多的10个
  • Top 10 series count by label value pairs: 标签对数量最多的10个

核心源码解读

  • 位置 D:\go_path\src\github.com\prometheus\prometheus\tsdb\index\postings.go

web侧调用入口

  • api /api/v1/status/tsdb
  • 代码位置 D:\go_path\src\github.com\prometheus\prometheus\web\api\v1\api.go
go 复制代码
func (api *API) serveTSDBStatus(*http.Request) apiFuncResult {
	s, err := api.db.Stats("__name__")
	if err != nil {
		return apiFuncResult{nil, &apiError{errorInternal, err}, nil, nil}
	}
	metrics, err := api.gatherer.Gather()
	if err != nil {
		return apiFuncResult{nil, &apiError{errorInternal, fmt.Errorf("error gathering runtime status: %s", err)}, nil, nil}
	}
	chunkCount := int64(math.NaN())
	for _, mF := range metrics {
		if *mF.Name == "prometheus_tsdb_head_chunks" {
			m := *mF.Metric[0]
			if m.Gauge != nil {
				chunkCount = int64(m.Gauge.GetValue())
				break
			}
		}
	}
	return apiFuncResult{tsdbStatus{
		HeadStats: HeadStats{
			NumSeries:     s.NumSeries,
			ChunkCount:    chunkCount,
			MinTime:       s.MinTime,
			MaxTime:       s.MaxTime,
			NumLabelPairs: s.IndexPostingStats.NumLabelPairs,
		},
		SeriesCountByMetricName:     convertStats(s.IndexPostingStats.CardinalityMetricsStats),
		LabelValueCountByLabelName:  convertStats(s.IndexPostingStats.CardinalityLabelStats),
		MemoryInBytesByLabelName:    convertStats(s.IndexPostingStats.LabelValueStats),
		SeriesCountByLabelValuePair: convertStats(s.IndexPostingStats.LabelValuePairsStats),
	}, nil, nil, nil}
}

底层调用的是 tsdb的Stats函数,传入__name__标签

tsdb 统计函数 Stats

  • 位置 D:\go_path\src\github.com\prometheus\prometheus\tsdb\index\postings.go

初始最大堆用作统计

go 复制代码
	metrics := &maxHeap{}
	labels := &maxHeap{}
	labelValueLength := &maxHeap{}
	labelValuePairs := &maxHeap{}
	numLabelPairs := 0

	metrics.init(maxNumOfRecords)
	labels.init(maxNumOfRecords)
	labelValueLength.init(maxNumOfRecords)
	labelValuePairs.init(maxNumOfRecords)

遍历双层map 获取 标签中value最多的10个

  • 把所有非空的标签算入统计 labels,值是e中id-set的长度
  • labels这个 最大堆统计的就是 Top 10 label names with value count,代表 标签中value最多的10个
go 复制代码
	for n, e := range p.m {
		if n == "" {
			continue
		}
		labels.push(Stat{Name: n, Count: uint64(len(e))})
	}

遍历双层map 获取 标签中value最多的10个

  • 遍历内层的map,如果name和传入的label一致,则加入metrics最大堆统计
  • metrics这个 最大堆统计的就是 Top 10 series count by metric names: metric_name匹配的series最多的10个
go 复制代码
	for n, e := range p.m {
        ...
		size = 0
		for name, values := range e {
			if n == label {
				metrics.push(Stat{Name: name, Count: uint64(len(values))})
			}
		}
	}

遍历双层map 获取 标签对数量最多的10个

  • 遍历内层的map,把name=value做统计算入labelValuePairs最大堆统计
  • labelValuePairs这个 最大堆统计的就是Top 10 series count by label value pairs: 标签对数量最多的10个
go 复制代码
	for n, e := range p.m {
        ...

		for name, values := range e {
            labelValuePairs.push(Stat{Name: n + "=" + name, Count: uint64(len(values))})
		}
	}

遍历双层map 获取 标签消耗内存最多的10个

  • 遍历内层的map,计算标签的value字符串长度 size,推入labelValueLength 最大堆统计
  • labelValueLength这个 最大堆统计的就是Top 10 label names with high memory usage: 标签消耗内存最多的10个
go 复制代码
	for n, e := range p.m {
		if n == "" {
			continue
		}
		size = 0
		for name, values := range e {
			size += uint64(len(name))
		}
		labelValueLength.push(Stat{Name: n, Count: size})
	}

get方法获取最大堆的结果

  • D:\go_path\src\github.com\prometheus\prometheus\tsdb\index\postingsstats.go
go 复制代码
func (m *maxHeap) get() []Stat {
	sort.Slice(m.Items, func(i, j int) bool {
		return m.Items[i].Count > m.Items[j].Count
	})
	return m.Items
}

本节重点介绍 :

  • 获取采集端的高基数metrics的tsdb页面解析
  • tsdb统计函数Stats源码解读
    • 依赖倒排索引统计
    • 是基于内存中的倒排索引 算最大堆取 top10
相关推荐
cungudafa37 分钟前
【IOS】Undefined symbol: _OBJC_CLASS_$_PAGFile
flutter·ios
_可乐无糖39 分钟前
iOS UI自动化 当执行次数增多后页面元素定位变慢的原因
ios·自动化
cungudafa40 分钟前
【IOS】编译缓存错误Library/Caches/com.apple.mobile.installd.staging
ios·缓存
我码玄黄2 小时前
Flutter踩坑:原生IOS页面向Flutter通信
前端·flutter·ios
微澜-13 小时前
查找萤石云IOS Sdk中的编解码接口
ios·萤石云
多彩电脑1 天前
Swift的可选绑定(Optional binding)
开发语言·ios·swift
hxx2211 天前
ios swift开发--ios远程推送通知配置
ios·swift
#摩斯先生1 天前
Swift从0开始学习 函数和闭包 day2
ios·xcode·swift
Adam.com1 天前
#Swift Automatic Initializer Inheritance
开发语言·ios·swift