• Metric模块源码解析


    分布式系统的监控告警及运维服务离不开指标监控,KaiwuDB 作为浪潮自主研发的一款分布式数据库自然也不例外。在兼顾强一致性、高可用分布式架构、在线水平扩展、企业级安全等特性下,KaiwuDB 的 metric 模块可提供监控指标,实现预先定义指标的周期性采集。同时,可以提供兼容 Prometheus 标准格式的 API 接口,方便与外部的 Prometheus 服务进行集成。

    KaiwuDB metric 模块收集各模块相关统计的 metric 信息,并将其作为 Prometheus 格式的指标储存起来用于进一步查阅,对判断 KaiwuDB 的运行情况有着重要作用,同时也是 KaiwuDB adminUI 指标的数据来源。本期内容将围绕下图展示的 metric 模块基本框架,带领大家深入了解 KaiwuDB metric 模块的源码,图中各模块的详细介绍将持续为大家更新。

    图片

    1、定义接口介绍

    1.IterableIterable
    IterableIterable提供了一个同步访问内部对象的方法。方法如下:

    GetName() string 返回指标名
    GetHelp() string 返回指标帮助文本
    GetMeasurement() string 返回指标的lable
    GetUnit() Unit 返回指标使用的单位
    GetMetadata() Metdata 返回指标的Metadata
    Inspect(func(interface{})) Inspect对每个包含的项调用给定的闭包
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.PrometheusExportable
    PrometheusExportable 是标准独立指标接口,可供指标导入 Prometheus。方法如下:

    GetName() string 返回指标名
    GetHelp() string 返回指标帮助文本
    GetType() *prometheusgo.MetricType 返回指标的Prometheus类型
    GetLables() []*prometheusgo.LabelPair Metadata中的一个方法,返回指标的标签
    ToPrometheusMetric() *prometheusgo.Metric 返回一个完成值填充的Prometheus指标
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.PrometheusIterable
    PrometheusIterable 是 PrometheusExportable 的扩展,用于指示该指标由增加父标签值的子指标组成。包含成员:PrometheusExportable。方法如下:

    Each([]*prometheusgo.LabelPair, func(metric *prometheusgo.Metric))
    “Each”获取与父指标相关联的标签对切片,并使用每个子指标调用所传递的函数
    
    • 1
    • 2

    2、Metric Metadata介绍

    Metadata 包含关于指标的元数据,它必须嵌入到每个 metric object 中。它用于将有关指标的信息导出到 Promethues 和 adminUI 图表。

    type Metadata struct {  
    Name        string           
    Help        string           
    Measurement string            
    Unit        Unit             
    MetricType  _go.MetricType    
    Labels      []*LabelPair     
    }  
    
    // 方法
    GetName() string  
    GetHelp() string  
    GetMeasurement() string  
    GetUnit() Unit  
    GetLabels() []*prometheusgo.LabelPair  
    Addlabel(name value string)//给一个指标添加标签/值映射
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    3、指标类型介绍

    1.HistogramHistogram
    在一段时间范围内对数据进行采样(通常是请求持续时间、响应大小等),并将其计入可配置的存储桶(bucket)中,后续可通过指定区间筛选样本,也可以统计样本总数,最后一般将数据展示为直方图。

    Prometheus 的 Histogram 是一种累积直方图,与上面的区间划分方式是有差别的。它的划分方式如下:假设每个 bucket 的宽度是 0.2s,那么第一个 bucket 表示响应时间小于等于 0.2s 的请求数量,第二个 bucket 表示响应时间小于等于 0.4s 的请求数量,以此类推。也就是说,每一个 bucket 的样本包含了之前所有 bucket 的样本,所以叫累积直方图。

    图片

    type Histogram {  
    Metadata  
    maxVal int64  
    mu     struct {  
    syncutil.Mutex  
    cumulative *hdrhistogram.Histogram  
    sliding    *slidingHistogram     
    }  
    //hdrhistogram.Histogram
    type Histogram struct {  
    lowestTrackableValue        int64  
    highestTrackableValue       int64  
    unitMagnitude               int64  
    significantFigures          int64  
    subBucketHalfCountMagnitude int32  
    subBucketHalfCount          int32  
    subBucketMask               int64  
    subBucketCount              int32  
    bucketCount                 int32  
    countsLen                   int32  
    totalCount                  int64  
    counts                      []int64  
    } 
    //slidingHistogram
    type slidingHistogram struct {  
    windowed *hdrhistogram.WindowedHistogram  
    nextT    time.Time  
    duration time.Duration  
    } 
    type WindowedHistogram struct {
    idx int
    h  []Histogram
    m  *Histogram
    Current *Histogram
    }
    
    //相关方法介绍
    func (h *Histogram) Windowed() (*hdrhistogram.Histogram, time.Duration)
    返回一份当前的窗口化直方图的数据和其中的时间间隔
    
    func (h *Histogram) Snapshot() *hdrhistogram.Histogram
    返回累积(即所有样本)直方图数据的副本
    
    func (h *Histogram) RecordValue(v int64)
    RecordValue将给定的值添加到直方图。记录超过该直方图配置最大值使用方法
    
    func (h *Histogram) TotalCount() int64
    TotalCount返回样本的(累计)数量
    
    func (h *Histogram) Min() int64
    返回最小值
    
    func (h *Histogram) Inspect(f func(interface{}))
    调用带有空字符串和接收方的闭包
    
    func (h *Histogram) GetType() *prometheusgo.MetricType
    返回此指标的Prometheus类型enum
    
    func (h *Histogram) ToPrometheusMetric() *prometheusgo.Metric
    返回正确类型的已填充的Prometheus度量值
    
    func (h *Histogram) GetMetadata() Metadata
    返回指标的元数据,包括Prometheus MetricType
    
    func NewHistogram(metadata Metadata, duration time.Duration, maxVal int64, sigFigs int) (*Histogram)
    实例化一个新histogram
    
    func NewLatency(metadata Metadata, histogramWindow time.Duration) *Histogram
    NewLatency
    返回一个带有适当默认值的直方图来跟踪延迟。数值以ns表示,截断为间隔[0,MaxLatency],并以1位精度记录(即误差在100ms时<10ms,在60s时<6s)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70

    2.Counter
    Counter 类型代表一种样本数据单调递增的指标,即只增不减,除非监控系统发生了重置。例如,你可以使用 Counter 类型的指标来表示服务的请求数、已完成的任务数、错误发生的次数等。

    type Counter struct {  
    Metadata  
    metrics.Counter  
    }  
    type Counter interface {  
    Clear()  
    Count() int64  
    Dec(int64)  
    Inc(int64)  
    Snapshot() Counter  
    }
    
    //相关方法介绍
    func (c *Counter) Dec(int64)
    Dec重载了metric.Counter的方法。不能使用这种方法,它只用于防止误用metric类型
    
    func (c *Counter) GetType() *prometheusgo.MetricType
    返回此指标的Prometheus类型enum
    
    func (c *Counter) Inspect(f func(interface{}))
    调用带有空字符串和接收方的闭包,即返回自己c
    
    func (c *Counter) MarshalJSON() ([]byte, error)
    MarshalJSON将数据封装到JSON
    
    func (c *Counter) GetMetadata() Metadata
    返回指标的元数据,包括Prometheus MetricType
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    3.Gauge
    Gauge 类型代表一种样本数据可以任意变化的指标,即可增可减。Guage 通常用于像温度或者内存使用率这种指标数据,也可以表示能随时增加或减少的“总数”,例如:当前并发请求的数量。

    type Gauge struct {  
    Metadata  
    value *int64  
    fn    func() int64  
    }
    
    //相关方法介绍
    func (g *Gauge) Snapshot() metrics.Gauge
    Snapshot返回Gauge的只读副本
    
    func (g *Gauge) Update(v int64)
    更新Gauge的值
    
    func (g *Gauge) Inc(i int64)
    增加Gauge的当前值
    
    func (g *Gauge) Dec(i int64)
    减少Gauge的当前值
    
    func (g *Gauge) Value() int64
    Value返回Gauge的当前值
    
    func (g *Gauge) GetType() *prometheusgo.MetricType
    返回此指标的Prometheus类型enum
    
    func (g *Gauge) ToPrometheusMetric() *prometheusgo.Metric
    返回此指标的Prometheus类型enum
    
    func (g *Gauge) GetMetadata() Metadata
    返回指标的元数据,包括Prometheus MetricType
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    4.Rate
    Rate 是用来计算某个指标在最近一个区间时间内的变化率。

    type Rate struct {  
    Metadata  
    mu       syncutil.Mutex // protects fields below  
    curSum   float64  
    wrapped  ewma.MovingAverage  
    interval time.Duration  
    nextT    time.Time  
    }  
    
    //相关方法介绍
    func (e *Rate) GetType() *prometheusgo.MetricType
    GetType返回该指标的Prometheus类型enum
    
    func (e *Rate) Inspect(f func(interface{}))
    Inspect用自身调用给定的闭包
    
    func (e *Rate) ToPrometheusMetric() *prometheusgo.Metric
    返回此指标的Prometheus类型enum
    
    func (c *Counter) MarshalJSON() ([]byte, error)
    MarshalJSON将数据封装到JSON
    
    func (e *Rate) GetMetadata() Metadata
    GetMetadata返回指标的元数据,包括Prometheus MetricType
    
    func (e *Rate) Value() float64
    Value返回Rate的当前值
    
    func (e *Rate) tick()
    Rate时间前进
    
    func (e *Rate) nextTick() time.Time
    返回Rate的当前时间。
    
    func (e *Rate) Add(v float64)
    添加将给定的测量值添加到Rate
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    4、注册器Registry介绍

    Registry 是 metric 的列表,它提供了一种处理指标的方法,可以将 metric 编组成 JSON,并生成 Prometheus 格式的 metric。同时可以给注册的指标打上标签,当导出到 Prometheus 时,这些标签将应用于它的所有指标。

    type Registry struct {  
    syncutil.Mutex  
    labels  []*prometheusgo.LabelPair  
    tracked []Iterable  
    }  
    
    //相关方法介绍
    func (r *Registry) AddLabel(name, value string)
    AddLabel为这个注册表添加一个标签/值对
    
    func (r *Registry) AddMetric(metric Iterable)
    AddMetric将传入的metric添加到注册表
    
    func (r *Registry) WriteMetricsMetadata(dest map[string]Metadata)
    WriteMetricsMetadata将所有跟踪metric的元数据写入参数映射
    
    func (r *Registry) Each(f func(name string, val interface{}))
    每个函数对所有metric调用给定的闭包
    
    func (r *Registry) MarshalJSON() ([]byte, error)
    格式化到JSON格式
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    5、注册新Registry步骤

    图片

    // 以txnMetric说明  
    //txn_metric.go  
    //声明定义的指标结构体类型  
    type TxnMetrics struct {  
    Commits         *metric.Counter  
    ...  
    }  
    //定义指标的metadata  
    var(  
    metaCommitsRates = metric.Metadata{  
    Name:        "txn.commits",  
    Help:        "Number of committed KV transactions (including 1PC)",  
    Measurement: "KV Transactions",  
    Unit:        metric.Unit_COUNT,  
    }  
    ...  
    )  
    //将定义的指标类型和metadata相关联  
    func MakeTxnMetrics(histogramWindow time.Duration) TxnMetrics {  
    return TxnMetrics{  
    Commits:                       metric.NewCounter(metaCommitsRates),  
    }  
    //server.go:  
    //注册进Registry  
    txnMetrics := kvcoord.MakeTxnMetrics(cfg.HistogramWindowInterval())  
    registry.AddMetricStruct(txnMetrics) 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
  • 相关阅读:
    关于python环境下的语音转文本,whisper或funASR
    第四章. Pandas进阶—日期数据处理
    第四章 路由基础
    小学生python游戏编程2----飞机大战1
    JMeter压测如何分配业务比例?
    unity OnMouse生命周期
    Windows下Core Audio APIs的使用简介
    【公众号备份】运维现状思考之字字珠玑
    企业固定资产盘点方案
    Java-KoTime:接口耗时监测与邮件通知接口耗时情况
  • 原文地址:https://blog.csdn.net/ZNBase/article/details/126605889