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
相关推荐
恋猫de小郭4 小时前
什么?Flutter 可能会被 SwiftUI/ArkUI 化?全新的 Flutter Roadmap
flutter·ios·swiftui
网安墨雨8 小时前
iOS应用网络安全之HTTPS
web安全·ios·https
福大大架构师每日一题10 小时前
37.1 prometheus管理接口源码讲解
ios·iphone·prometheus
Cairry.1 天前
WatchAlert - 开源多数据源告警引擎
云原生·开源·prometheus
BangRaJun1 天前
LNCollectionView-替换幂率流体
算法·ios·设计
Mitch3111 天前
【漏洞复现】CVE-2023-37461 Arbitrary File Writing
web安全·网络安全·prometheus·metersphere·漏洞复现
刘小哈哈哈1 天前
iOS 多个输入框弹出键盘处理
macos·ios·cocoa
靴子学长1 天前
iOS + watchOS Tourism App(含源码可简单复现)
mysql·ios·swiftui
一如初夏丿2 天前
xcode15 报错 does not contain ‘libarclite‘
ios·xcode
杨武博2 天前
ios 混合开发应用白屏问题
ios