Prometheus

Prometheus

Prometheus配置文件热加载

运维 push 发表了文章 0 个评论 4372 次浏览 2020-11-05 16:36 来自相关话题

Promtheus的TSDB时序数据库在存储了大量的数据后,每次重启Prometheus进程的时间会越来越慢, 而且日常运维工作中会经常调整Prometheus的配置文件信息,比如一些静态配置,实际上Prometheus提供了在运行时热加载配置信息的功能 ...查看全部

Promtheus的TSDB时序数据库在存储了大量的数据后,每次重启Prometheus进程的时间会越来越慢, 而且日常运维工作中会经常调整Prometheus的配置文件信息,比如一些静态配置,实际上Prometheus提供了在运行时热加载配置信息的功能,在这里介绍一下。


Prometheus配置热加载提供了2种方法:


  1. kill -HUP pid 发送SIGHUP信号方法
  2. 通过Prometheus服务API接口,发送发送一个POST请求到/-/reload

Tips: 从 Prometheus2.0 开始,热加载功能是默认关闭的,如需开启,需要在启动 Prometheus 的时候,添加 --web.enable-lifecycle 参数。



我个人更倾向于采用curl -XPOST http://localhost:9090/-/reload 的方式,因为每次reload过后, pid会改变,使用kill方式需要找到当前进程号。


如果配置热加载成功,Prometheus会打印出下面的log:


... msg="Loading configuration file" filename=prometheus.yml ...

下面我们来看看这两种方式内部实现原理。


第一种方法: 通过 kill 命令的 HUP (hang up) 参数实现
首先Prometheus在 cmd/promethteus/main.go 中实现了对进程系统调用监听,如果收到syscall.SIGHUP信号,将执行reloadConfig函数。


代码类似如下:


{
// Reload handler.

// Make sure that sighup handler is registered with a redirect to the channel before the potentially
// long and synchronous tsdb init.
hup := make(chan os.Signal, 1)
signal.Notify(hup, syscall.SIGHUP)
cancel := make(chan struct{})
g.Add(
func() error {
<-reloadReady.C

for {
select {
case <-hup:
if err := reloadConfig(cfg.configFile, logger, noStepSubqueryInterval, reloaders...); err != nil {
level.Error(logger).Log("msg", "Error reloading config", "err", err)
}
case rc := <-webHandler.Reload():
if err := reloadConfig(cfg.configFile, logger, noStepSubqueryInterval, reloaders...); err != nil {
level.Error(logger).Log("msg", "Error reloading config", "err", err)
rc <- err
} else {
rc <- nil
}
case <-cancel:
return nil
}
}

},
func(err error) {
// Wait for any in-progress reloads to complete to avoid
// reloading things after they have been shutdown.
cancel <- struct{}{}
},
)
}

第二种:通过 web 模块的 /-/reload请求实现:


首先 Prometheus 在 web(web/web.go) 模块中注册了一个 POST 的 http 请求 /-/reload, 它的 handler 是 web.reload 函数,该函数主要向 web.reloadCh chan 里面发送一个 error。


其次在Prometheus 的cmd/promethteus/main.go中有个单独的 goroutine 来监听web.reloadCh,当接受到新值的时候会执行 reloadConfig 函数。


func() error {
<-reloadReady.C

for {
select {
case <-hup:
if err := reloadConfig(cfg.configFile, logger, noStepSubqueryInterval, reloaders...); err != nil {
level.Error(logger).Log("msg", "Error reloading config", "err", err)
}
case rc := <-webHandler.Reload():
if err := reloadConfig(cfg.configFile, logger, noStepSubqueryInterval, reloaders...); err != nil {
level.Error(logger).Log("msg", "Error reloading config", "err", err)
rc <- err
} else {
rc <- nil
}
case <-cancel:
return nil
}
}

},

Prometheus内部提供了成熟的hot reload方案,这大大方便配置文件的修改和重新加载,在Prometheus生态中,很多Exporter也采用类似约定的实现方式。

Prometheus时间序列监控方案

开源项目 push 发表了文章 0 个评论 9461 次浏览 2017-05-26 00:00 来自相关话题

最近一直在折腾时序类型的数据库,经过一段时间项目应用,觉得十分不错。而Prometheus又是刚刚推出不久的开源方案,中文资料较少,所以打算写一系列应用的实践过程分享一下。   Prometheus 是什么? ...查看全部
最近一直在折腾时序类型的数据库,经过一段时间项目应用,觉得十分不错。而Prometheus又是刚刚推出不久的开源方案,中文资料较少,所以打算写一系列应用的实践过程分享一下。
 


Prometheus 是什么?


Prometheus是一套开源的监控&报警&时间序列数据库的组合,起始是由SoundCloud公司开发的。随着发展,越来越多公司和组织接受采用Prometheus,社会也十分活跃,他们便将它独立成开源项目,并且有公司来运作。google SRE的书内也曾提到跟他们BorgMon监控系统相似的实现是Prometheus。现在最常见的Kubernetes容器管理系统中,通常会搭配Prometheus进行监控。


Prometheus 的优点


  • 非常少的外部依赖,安装使用超简单
  • 已经有非常多的系统集成 例如:docker HAProxy Nginx JMX等等
  • 服务自动化发现
  • 直接集成到代码
  • 设计思想是按照分布式、微服务架构来实现的
 

Prometheus 的特性

  • 自定义多维度的数据模型
  • 非常高效的存储 平均一个采样数据占 ~3.5 bytes左右,320万的时间序列,每30秒采样,保持60天,消耗磁盘大概228G。
  • 强大的查询语句
  • 轻松实现数据可视化
 等等, 相对于Graphite这种产品,还是有不少优点的。最让我觉得不错的是非常优秀的写性能和读取性能,它数据结构实现和OpenTSDB是有相似之处,有兴趣可以看看这个文档:解密OpenTSDB的表存储优 。

Prometheus 的系统架构

prometheus.png
它的服务过程是这样的 Prometheus daemon 负责定时去目标上抓取 metrics(指标) 数据,每个抓取目标需要暴露一个http服务的接口给它定时抓取。Prometheus支持通过配置文件、文本文件、zookeeper、Consul、DNS SRV lookup等方式指定抓取目标。Alertmanager 是独立于Prometheus的一个组件,可以支持Prometheus的查询语句,提供十分灵活的报警方式。Prometheus支持很多方式的图表可视化,例如十分精美的Grafana,自带的Promdash,以及自身提供的模版引擎等等,还提供HTTP API的查询方式,自定义所需要的输出。PushGateway这个组件是支持Client主动推送 metrics 到PushGateway,而Prometheus只是定时去Gateway上抓取数据。如果有使用过statsd的用户,则会觉得这十分相似,只是statsd是直接发送给服务器端,而Prometheus主要还是靠进程主动去抓取。

Prometheus 的数据模型

Prometheus 从根本上所有的存储都是按时间序列去实现的,相同的 metrics(指标名称) 和 label(一个或多个标签) 组成一条时间序列,不同的label表示不同的时间序列。为了支持一些查询,有时还会临时产生一些时间序列存储。 metrics name & label 指标名称和标签每条时间序列是由唯一的 指标名称 和 一组 标签 (key=value)的形式组成。指标名称 一般是给监测对像起一名字,例如 http_requests_total 这样,它有一些命名规则,可以包字母数字_之类的的。通常是以应用名称开头_监测对像_数值类型_单位这样, 例如:[list=1]
  • push_total
  • userlogin_mysql_duration_seconds
  • app_memory_usage_bytes
  •  标签 就是对一条时间序列不同维度的识别了,例如 一个http请求用的是POST还是GET,它的endpoint是什么,这时候就要用标签去标记了, 最终形成的标识便是这样了:
    http_requests_total{method="POST",endpoint="/api/tracks"}
    记住,针对http_requests_total这个metrics name 无论是增加标签还是删除标签都会形成一条新的时间序列。查询语句就可以跟据上面标签的组合来查询聚合结果了。如果以传统数据库的理解来看这条语句,则可以考虑 http_requests_total是表名,标签是字段,而timestamp是主键,还有一个float64字段是值了。(Prometheus里面所有值都是按float64存储)。

    Prometheus 的四种数据类型

    Counter:
    • Counter 用于累计值,例如 记录 请求次数、任务完成数、错误发生次数。
    • 一直增加,不会减少。
    • 重启进程后,会被重置。
    例如:http_response_total{method="GET",endpoint="/api/tracks"} 10010秒后抓取 http_response_total{method="GET",endpoint="/api/tracks"} 100
    Gauge:
    • Gauge 常规数值,例如 温度变化、内存使用变化。
    • 可变大,可变小。
    • 重启进程后,会被重置
    例如: memory_usage_bytes{host="master-01"} 100 < 抓取值memory_usage_bytes{host="master-01"} 30memory_usage_bytes{host="master-01"} 50memory_usage_bytes{host="master-01"} 80 < 抓取值
    Histogram:
    • Histogram 可以理解为柱状图的意思,常用于跟踪事件发生的规模,例如:请求耗时、响应大小。它特别之处是可以对记录的内容进行分组,提供 count 和 sum 全部值的功能。
    例如:{小于10=5次,小于20=1次,小于30=2次},count=7次,sum=7次的求和值
    sum.png
     Summary:
    • Summary和Histogram十分相似,常用于跟踪事件发生的规模,例如:请求耗时、响应大小。同样提供 count 和 sum 全部值的功能。
    • 例如:count=7次,sum=7次的值求值
    • 它提供一个quantiles的功能,可以按%比划分跟踪的结果。例如:quantile取值0.95,表示取采样值里面的95%数据。

     
    分享阅读原文:http://www.cnblogs.com/vovlie/p/Prometheus_CONCEPTS.html 

    Prometheus配置文件热加载

    运维 push 发表了文章 0 个评论 4372 次浏览 2020-11-05 16:36 来自相关话题

    Promtheus的TSDB时序数据库在存储了大量的数据后,每次重启Prometheus进程的时间会越来越慢, 而且日常运维工作中会经常调整Prometheus的配置文件信息,比如一些静态配置,实际上Prometheus提供了在运行时热加载配置信息的功能 ...查看全部

    Promtheus的TSDB时序数据库在存储了大量的数据后,每次重启Prometheus进程的时间会越来越慢, 而且日常运维工作中会经常调整Prometheus的配置文件信息,比如一些静态配置,实际上Prometheus提供了在运行时热加载配置信息的功能,在这里介绍一下。


    Prometheus配置热加载提供了2种方法:


    1. kill -HUP pid 发送SIGHUP信号方法
    2. 通过Prometheus服务API接口,发送发送一个POST请求到/-/reload

    Tips: 从 Prometheus2.0 开始,热加载功能是默认关闭的,如需开启,需要在启动 Prometheus 的时候,添加 --web.enable-lifecycle 参数。



    我个人更倾向于采用curl -XPOST http://localhost:9090/-/reload 的方式,因为每次reload过后, pid会改变,使用kill方式需要找到当前进程号。


    如果配置热加载成功,Prometheus会打印出下面的log:


    ... msg="Loading configuration file" filename=prometheus.yml ...

    下面我们来看看这两种方式内部实现原理。


    第一种方法: 通过 kill 命令的 HUP (hang up) 参数实现
    首先Prometheus在 cmd/promethteus/main.go 中实现了对进程系统调用监听,如果收到syscall.SIGHUP信号,将执行reloadConfig函数。


    代码类似如下:


    {
    // Reload handler.

    // Make sure that sighup handler is registered with a redirect to the channel before the potentially
    // long and synchronous tsdb init.
    hup := make(chan os.Signal, 1)
    signal.Notify(hup, syscall.SIGHUP)
    cancel := make(chan struct{})
    g.Add(
    func() error {
    <-reloadReady.C

    for {
    select {
    case <-hup:
    if err := reloadConfig(cfg.configFile, logger, noStepSubqueryInterval, reloaders...); err != nil {
    level.Error(logger).Log("msg", "Error reloading config", "err", err)
    }
    case rc := <-webHandler.Reload():
    if err := reloadConfig(cfg.configFile, logger, noStepSubqueryInterval, reloaders...); err != nil {
    level.Error(logger).Log("msg", "Error reloading config", "err", err)
    rc <- err
    } else {
    rc <- nil
    }
    case <-cancel:
    return nil
    }
    }

    },
    func(err error) {
    // Wait for any in-progress reloads to complete to avoid
    // reloading things after they have been shutdown.
    cancel <- struct{}{}
    },
    )
    }

    第二种:通过 web 模块的 /-/reload请求实现:


    首先 Prometheus 在 web(web/web.go) 模块中注册了一个 POST 的 http 请求 /-/reload, 它的 handler 是 web.reload 函数,该函数主要向 web.reloadCh chan 里面发送一个 error。


    其次在Prometheus 的cmd/promethteus/main.go中有个单独的 goroutine 来监听web.reloadCh,当接受到新值的时候会执行 reloadConfig 函数。


    func() error {
    <-reloadReady.C

    for {
    select {
    case <-hup:
    if err := reloadConfig(cfg.configFile, logger, noStepSubqueryInterval, reloaders...); err != nil {
    level.Error(logger).Log("msg", "Error reloading config", "err", err)
    }
    case rc := <-webHandler.Reload():
    if err := reloadConfig(cfg.configFile, logger, noStepSubqueryInterval, reloaders...); err != nil {
    level.Error(logger).Log("msg", "Error reloading config", "err", err)
    rc <- err
    } else {
    rc <- nil
    }
    case <-cancel:
    return nil
    }
    }

    },

    Prometheus内部提供了成熟的hot reload方案,这大大方便配置文件的修改和重新加载,在Prometheus生态中,很多Exporter也采用类似约定的实现方式。

    Prometheus时间序列监控方案

    开源项目 push 发表了文章 0 个评论 9461 次浏览 2017-05-26 00:00 来自相关话题

    最近一直在折腾时序类型的数据库,经过一段时间项目应用,觉得十分不错。而Prometheus又是刚刚推出不久的开源方案,中文资料较少,所以打算写一系列应用的实践过程分享一下。   Prometheus 是什么? ...查看全部
    最近一直在折腾时序类型的数据库,经过一段时间项目应用,觉得十分不错。而Prometheus又是刚刚推出不久的开源方案,中文资料较少,所以打算写一系列应用的实践过程分享一下。
     


    Prometheus 是什么?


    Prometheus是一套开源的监控&报警&时间序列数据库的组合,起始是由SoundCloud公司开发的。随着发展,越来越多公司和组织接受采用Prometheus,社会也十分活跃,他们便将它独立成开源项目,并且有公司来运作。google SRE的书内也曾提到跟他们BorgMon监控系统相似的实现是Prometheus。现在最常见的Kubernetes容器管理系统中,通常会搭配Prometheus进行监控。


    Prometheus 的优点


    • 非常少的外部依赖,安装使用超简单
    • 已经有非常多的系统集成 例如:docker HAProxy Nginx JMX等等
    • 服务自动化发现
    • 直接集成到代码
    • 设计思想是按照分布式、微服务架构来实现的
     

    Prometheus 的特性

    • 自定义多维度的数据模型
    • 非常高效的存储 平均一个采样数据占 ~3.5 bytes左右,320万的时间序列,每30秒采样,保持60天,消耗磁盘大概228G。
    • 强大的查询语句
    • 轻松实现数据可视化
     等等, 相对于Graphite这种产品,还是有不少优点的。最让我觉得不错的是非常优秀的写性能和读取性能,它数据结构实现和OpenTSDB是有相似之处,有兴趣可以看看这个文档:解密OpenTSDB的表存储优 。

    Prometheus 的系统架构

    prometheus.png
    它的服务过程是这样的 Prometheus daemon 负责定时去目标上抓取 metrics(指标) 数据,每个抓取目标需要暴露一个http服务的接口给它定时抓取。Prometheus支持通过配置文件、文本文件、zookeeper、Consul、DNS SRV lookup等方式指定抓取目标。Alertmanager 是独立于Prometheus的一个组件,可以支持Prometheus的查询语句,提供十分灵活的报警方式。Prometheus支持很多方式的图表可视化,例如十分精美的Grafana,自带的Promdash,以及自身提供的模版引擎等等,还提供HTTP API的查询方式,自定义所需要的输出。PushGateway这个组件是支持Client主动推送 metrics 到PushGateway,而Prometheus只是定时去Gateway上抓取数据。如果有使用过statsd的用户,则会觉得这十分相似,只是statsd是直接发送给服务器端,而Prometheus主要还是靠进程主动去抓取。

    Prometheus 的数据模型

    Prometheus 从根本上所有的存储都是按时间序列去实现的,相同的 metrics(指标名称) 和 label(一个或多个标签) 组成一条时间序列,不同的label表示不同的时间序列。为了支持一些查询,有时还会临时产生一些时间序列存储。 metrics name & label 指标名称和标签每条时间序列是由唯一的 指标名称 和 一组 标签 (key=value)的形式组成。指标名称 一般是给监测对像起一名字,例如 http_requests_total 这样,它有一些命名规则,可以包字母数字_之类的的。通常是以应用名称开头_监测对像_数值类型_单位这样, 例如:[list=1]
  • push_total
  • userlogin_mysql_duration_seconds
  • app_memory_usage_bytes
  •  标签 就是对一条时间序列不同维度的识别了,例如 一个http请求用的是POST还是GET,它的endpoint是什么,这时候就要用标签去标记了, 最终形成的标识便是这样了:
    http_requests_total{method="POST",endpoint="/api/tracks"}
    记住,针对http_requests_total这个metrics name 无论是增加标签还是删除标签都会形成一条新的时间序列。查询语句就可以跟据上面标签的组合来查询聚合结果了。如果以传统数据库的理解来看这条语句,则可以考虑 http_requests_total是表名,标签是字段,而timestamp是主键,还有一个float64字段是值了。(Prometheus里面所有值都是按float64存储)。

    Prometheus 的四种数据类型

    Counter:
    • Counter 用于累计值,例如 记录 请求次数、任务完成数、错误发生次数。
    • 一直增加,不会减少。
    • 重启进程后,会被重置。
    例如:http_response_total{method="GET",endpoint="/api/tracks"} 10010秒后抓取 http_response_total{method="GET",endpoint="/api/tracks"} 100
    Gauge:
    • Gauge 常规数值,例如 温度变化、内存使用变化。
    • 可变大,可变小。
    • 重启进程后,会被重置
    例如: memory_usage_bytes{host="master-01"} 100 < 抓取值memory_usage_bytes{host="master-01"} 30memory_usage_bytes{host="master-01"} 50memory_usage_bytes{host="master-01"} 80 < 抓取值
    Histogram:
    • Histogram 可以理解为柱状图的意思,常用于跟踪事件发生的规模,例如:请求耗时、响应大小。它特别之处是可以对记录的内容进行分组,提供 count 和 sum 全部值的功能。
    例如:{小于10=5次,小于20=1次,小于30=2次},count=7次,sum=7次的求和值
    sum.png
     Summary:
    • Summary和Histogram十分相似,常用于跟踪事件发生的规模,例如:请求耗时、响应大小。同样提供 count 和 sum 全部值的功能。
    • 例如:count=7次,sum=7次的值求值
    • 它提供一个quantiles的功能,可以按%比划分跟踪的结果。例如:quantile取值0.95,表示取采样值里面的95%数据。

     
    分享阅读原文:http://www.cnblogs.com/vovlie/p/Prometheus_CONCEPTS.html 
    Prometheus是一套开源的监控&报警&时间序列数据库的组合,起始是由SoundCloud公司开发的。随着发展,越来越多公司和组织接受采用Prometheus,社会也十分活跃,他们便将它独立成开源项目,并且有公司来运作。