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
相关推荐
得物技术9 小时前
得物 iOS 启动优化之 Building Closure
ios·性能优化
goto_w17 小时前
uniapp上使用webview与浏览器交互,支持三端(android、iOS、harmonyos next)
android·vue.js·ios·uni-app·harmonyos
鸿蒙布道师1 天前
鸿蒙NEXT开发对象工具类(TS)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
刘小哈哈哈1 天前
封装了一个iOS多分区自适应宽度layout
macos·ios·cocoa
布多2 天前
Tagged Pointer:苹果工程师的内存优化艺术
ios·源码
Rudon滨海渔村2 天前
新旧iPhone相册复制 - 相册图片视频对拷 - 换机 - 迁移设备数据 - 免费开源爱思助手
ios·iphone
清晨細雨2 天前
UniApp集成极光推送详细教程
android·ios·uni-app·极光推送
ii_best3 天前
iOS 按键越狱脚本支持一键新机软件教程
ios
企鹅侠客3 天前
Prometheus operator怎么添加targets和告警规则
运维·云原生·kubernetes·prometheus·pod
lilili啊啊啊3 天前
查看iphone手机的使用记录-克魔实战
ios·智能手机·iphone