Metric模块源码解析

广告位

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

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

Metric模块源码解析

1、定义接口介绍

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

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

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

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

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

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

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)//给一个指标添加标签/值映射 

3、指标类型介绍

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

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

Metric模块源码解析

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) 

2.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 

3.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 

4.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 

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格式 

5、注册新Registry步骤

Metric模块源码解析

// 以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)  

开务数据库是一款浪潮集团核心研发的先进、安全的云原生分布式数据库;具备云原生、多中心、高可用、事务强一致等特性,满足 HTAP 场景需求。业务范围覆盖能源、工业互联网、政务、教育、金融等多行业。我们是一支平均年龄 30 岁的年轻团队,在短短不到三年的时间里,我们已取得近 300 项发明专利受理,10 项自有产品软著授权。热烈欢迎广大伙伴加入我们的团队,热门岗位火热招聘中,简历投递邮箱: zhoubeili@inspur.com / bixueting@inspur.com

数据库存储内核研发工程师

工作职责:

1、负责存储子系统的研发路线规划、架构设计和关键技术问题攻关;

2、负责编写功能测试用例,测试工具进行系统验证;

3、负责数据库的系统性能诊断与调优;

4、负责数据库相关关键技术的预研和在团队中的引导;

5、深入理解业务场景的数据库存储需求,针对性的为不同业务场景提供最合适的存储方案。

任职要求:

1、学历:本科或者本科以上学历;

2、专业:计算机或相关专业;

3、专业知识:

— 3 年及以上 GO/C++ 开发经验;

— 精通 C/C++/GO 语言,Linux 系统编程。熟悉无锁数据结构,熟悉现代硬件体系结构 (CPU/Cache/Memory/Storage), 熟悉并发编程;

— 熟练使用 MySQL、PostgeSQL 等主流数据库;

— 熟悉数据库存储系统的基本理论,熟悉事务处理,日志与恢复策略,多版本并发控制技术的实现,对数据库的基本理论和内部实现机制有深刻的理解;

— 技术视野开阔,有一定的系统性能优化经验,掌握各种性能诊断工具和各种优化方法;

— 熟悉时序数据库,有实际的时序数据库开发经验优先;

— 熟悉 RocksDB、Arrow、Parquet 等开源存储项目源码者优先。

Base 地: 上海 / 天津 / 济南 / 北京

数据库方案工程师

工作职责:

1、负责分布式数据库,或其相关工具、平台等产品的梳理、规划、设计和推进工作;

2、进行解决方案的调研、设计和验证;

3、设计、撰写和维护产品红皮书;

4、跨部门沟通,协调各类资源以确保产品顺利上线,推进产品迭代。

任职要求:

1、5 年以上的数据库运维及方案设计经验(ORACLE/Mysql/PostgreSQL 任意一种),对部署,优化,灾备,恢复,高可用有实际经验;

2、1 年左右的分布式数据库经验,了解国内任意一款分布式数据库,有部署,POC,问题处理经验;

3、对 OLTP 和 OLAP 系统或其中一种有实际运维设计经验;

4、对数据库灾备,同步方案有实际项目经验;

5、会一种数据库 benchmark 工具,设计相应场景进行测试并结合已有经验给与相应调整优化;

6、有基本的编程能力,如 go,shell,python 其中一项,可以写简单程序对数据库进行并发测试,功能验证;

7、有项目管理能力,很好的沟通能力,可以与开发人员顺畅沟通,并于合作高校学生完成实验及文档编写;

8、扎实的技术,linux 和数据库方面有一定积累,能对开发人员及学生进行一定指导,促使相关工作顺利推进;

9、较强的文档编写组织能力,根据实验文档及相关手册,编写用户解决方案手册;

10、有一定语言表达能力,能做数据库相关功能培训。

Base 地: 上海 / 天津 / 济南 / 北京

本文来自网络,不代表技术学习分享_一航技术立场,转载请注明出处。

作者: 一航技术

上一篇
下一篇
广告位

发表回复

返回顶部