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
相关推荐
CocoaKier8 小时前
苹果商店详情顶部头图已面向所有开发者开放!
ios·apple
茶底世界之下8 小时前
同一张街拍,两种表达:用 Awaking 试一次高对比黑白
ios
调试人生的显微镜11 小时前
iOS开发入门:Interface Builder、基础控件及UITextField详解
后端·ios
茶底世界之下17 小时前
动态切换 nearest / linear 时,为什么不能只替换 sampler
ios·swift
传奇开心果编程2 天前
【Compose Multiplatform 跨端开发学与练】第7课 平台适配与互操作
android·windows·学习·ui·ios·kotlin·composer
爱琴孩2 天前
记一次Prometheus的WAL异常,导致服务器磁盘占用过高
prometheus·wal
传奇开心果编程2 天前
【Compose Multiplatform 跨端开发学与练】第5课 网络与数据层
android·网络·学习·ui·ios·kotlin·composer
茶底世界之下2 天前
视频预览切换为何会闪回旧帧:用 generation + mode identity 管住异步回调
ios·swift
老李IT笔记2 天前
从备份恢复会把管理状态带回来吗:iOS 27 之后答案变了|MDM.Plus
ios·智能手机
谢亮_vipxieliang2 天前
Go 接口设计原则核心知识点
开发语言·ios·golang