prometheus数据结构和压缩原理讲解

Prometheus通过高效的存储方式管理时间序列数据,采用FNV哈希算法和LevelDB存储引擎确保数据的快速读写及高可用性。它以1KB为单位进行数据块管理,并提供了多种数据编码方式供用户选择。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Prometheus有着非常高效的时间序列数据存储方法,每个采样数据仅仅占用3.5byte左右空间,上百万条时间序列,30秒间隔,保留60天,大概花了200多G(引用官方PPT)。
接下来让我们看看他的原理。

Prometheus内部主要分为三大块,Retrieval是负责定时去暴露的目标页面上去抓取采样指标数据,Storage是负责将采样数据写磁盘,PromQL是Prometheus提供的查询语言模块。

从最原始的抓取数据上来看,基本是这个样子,timestamp是当前抓取时间戳:

每个Metric name代表了一类的指标,他们可以携带不同的Labels,每个Metric name + Label组合成代表了一条时间序列的数据。
例如图上的数据:


 
  1. http_requests_total{status="200",method="GET"}

  2. http_requests_total{status="404",method="GET"}

表示了两条不同的时间序列。

在Prometheus的世界里面,所有的数值都是64bit的。每条时间序列里面记录的其实就是64bit timestamp(时间戳) + 64bit value(采样值)。

而对于时间序列的基本特性来说,通常是过去的数据一般是只读的,是不会变更的,当前时间的数据才会可能在写,模式如下图:

根据上面的分析,时间序列的存储似乎可以设计成key-value存储的方式(基于BigTable)。

进一步拆分,可以像下面这样子:

上图的第二条样式就是现在Prometheus内部的表现形式了,__name__是特定的label标签,代表了metric name。

再回顾一下Prometheus的整体流程:

上面提到了K-V存储,当然是使用了LevelDB的引擎,它的特点是顺序读写性能非常高,这是非常符合时间序列的存储的。

为了得到顺序的时间序列哈希索引值,Prometheus是这样处理的:

FNV哈希算法全名为Fowler-Noll-Vo算法,是以三位发明人Glenn Fowler,Landon Curt Noll,Phong Vo的名字来命名的,最早在1991年提出。
FNV能快速hash大量数据并保持较小的冲突率,它的高度分散使它适用于hash一些非常相近的字符串,比如URL,hostname,文件名,text,IP地址等。

1KB Chunks

在Prometheus的世界中,无论是内存还是磁盘,它都是以1KB单位分成块来操作的。(新出的Prometheus 2.0对存储底层做了很大改动,专门针对SSD的写放大进行了优化,提高SSD的读写性能和读写次数等。)

整体流程是 抓取数据 -> 写到head chunk,写满1KB,就再生成新的块,完成的块,是不可再变更的 -> 根据配置文件的设置,有一部份chunk会被保留在内存里,按照LRU算法,定期将块写进磁盘文件内。

注意: 一条时间序列,保存到一个磁盘文件内。

时间序列的保留维护

在Prometheus的启动选项中,有一项storage.local.retention可以设置数据自动保留多长时间,例如24h,表示数据超过24小时内的将会自动清除,类似于zabbix的housekeeping功能。storage.local.series-file-shrink-ratio可以按一定的比例保留数据。

关于Chunk 块编码的剖析

Prometheus 提供三种不同类型的块编码,用户可以在Prometheus启动时指定最新的编码方式,-storage.local.chunk-encoding-version,有效值是0,1,2。

版本0的编码是较老版本上的Prometheus上使用的,新版本已经不再建议使用的。

版本1是当前版本默认提供的编码方式,它相对于0版有较好的压缩能力,而且在一个块内,有较高的访问速度,当然版本0的编码速度是最快的,但是相对版本1,速度优势不是特别明显。

版本2提供了一个更高的压缩比例,编码和解码需要耗更多的CPU,当然,这是取决于查询的数据集有多大。通常如果是较少的查询,仅用于存档的数据,可以使用这种编码。

对比:

Chunk版本号每个采样点所占字节耗CPU核块编码耗时
13.31.62.9s
21.32.44.9s

V0 结构

V1 结构

V2 结构

Prometheus是如何访止数据丢失的呢?例如发生异常关闭或者什么别的情况?它提供了一个Checkpointing功能,对于内存里面的块,Prometheus 使用了一个checkpoint file 去同步写入磁盘,类似于Hbase的WAL原理,当发生crash时,先从checkpoint file去恢复数据。

 
<think>好的,用户想详细了解Prometheus监控系统,包括架构、配置使用教程。我需要先回忆Prometheus的核心组件工作原理。首先,Prometheus的主要架构包括Server、Client Libraries、Pushgateway、Exporters、Alertmanager以及服务发现等部分。 用户提到的引用中提到了官方架构图,需要确保在回答中涵盖这些组件。引用[1]提到Prometheus是一个开源的监控与时间序列数据库系统,引用[2]提到了服务发现方法Pushgateway,引用[3]则指向了中文技术文档,可能需要参考其中的时间序列数据部分。 接下来,需要分块介绍架构。首先从Server开始,解释其抓取存储机制。然后说明Client LibrariesExporters的作用,比如Node Exporter。Pushgateway用于短生命周期的任务,这点需要强调。Alertmanager处理报警,服务发现部分可以举例static_configsconsul_sd_configs等,如引用[2]中提到的。 配置部分需要给出一个基本的prometheus.yml示例,说明global、scrape_configs等部分,特别是static_configs的目标配置。同时提到其他服务发现方式,如ec2_sd_configs,引用[2]的内容需要在这里引用。 使用教程部分,可以分步骤:安装、配置监控目标、使用表达式查询、设置告警集成可视化工具如Grafana。每个步骤简要说明,并提示参考官方文档或引用中的链接,比如引用[3]的中文文档。 相关问题需要围绕用户可能感兴趣的扩展内容,比如与其他监控系统的对比、优化存储、告警规则编写、Kubernetes中的使用以及高可用方案。这些问题需要自然引出,帮助用户深入探索。 需要检查LaTeX格式是否正确,所有数学表达式用$...$,独立公式用$$...$$,但当前内容可能不涉及数学公式,所以可能不需要。但如果有性能分析中的公式,比如计算内存使用,可能需要使用,例如时间序列存储的计算,但用户问题中没有涉及,所以可能不需要。 最后确保引用正确添加到对应的部分,例如在架构中的服务发现部分添加[^2],在配置部分提到Pushgateway时引用,在时间序列数据部分引用[^3]。确保回答结构清晰,分点说明,使用代码块展示配置示例,语言用中文,符合用户要求。</think>### Prometheus 监控系统详解 #### 一、系统架构 Prometheus 是一个开源的监控与时间序列数据库系统,其核心架构包含以下组件: 1. **Prometheus Server** 负责定时从配置的目标(如Exporters、应用程序)拉取(Pull)指标数据,并存储在本地时间序列数据库中。数据存储采用自定义的压缩算法,支持高效查询[^1]。 2. **Client Libraries** 提供多种编程语言(如Go、Java、Python)的客户端库,供应用程序集成并暴露监控指标。 3. **Exporters** 用于将第三方系统(如MySQL、Node Exporter)的指标转换为Prometheus兼容格式。例如,`node_exporter`用于收集服务器硬件OS指标。 4. **Pushgateway** 适用于短暂任务(如定时任务)的监控,任务将指标推送到Pushgateway,再由Prometheus Server拉取[^2]。 5. **Alertmanager** 处理Prometheus发送的告警,支持去重、分组路由(如邮件、Slack通知)。 6. **服务发现** 支持静态配置(`static_configs`)动态发现(如Consul、Kubernetes、EC2)[^2]。 #### 二、配置示例 以下是一个基本的`prometheus.yml`配置: ```yaml global: scrape_interval: 15s # 抓取间隔 scrape_configs: - job_name: "node_exporter" # 监控目标组名称 static_configs: - targets: ["192.168.1.100:9100", "192.168.1.101:9100"] # 目标地址 - job_name: "pushgateway" honor_labels: true # 保留Pushgateway的标签 static_configs: - targets: ["pushgateway:9091"] ``` #### 三、使用教程 1. **安装与启动** 通过Docker或二进制包部署Prometheus ServerExporters: ```bash docker run -p 9090:9090 -v /path/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus ``` 2. **配置监控目标** 修改`prometheus.yml`,添加需监控的Exporter地址,或使用服务发现(如Kubernetes自动发现Pod)。 3. **查询数据** 使用PromQL在Web界面(`http://localhost:9090/graph`)查询指标,例如: ```promql rate(node_cpu_seconds_total{mode="idle"}[5m]) # 计算CPU空闲率 ``` 4. **设置告警规则** 在`rules.yml`中定义告警条件,例如检测服务宕机: ```yaml groups: - name: example rules: - alert: InstanceDown expr: up == 0 # 目标健康状态为0时触发 for: 5m labels: severity: critical annotations: summary: "实例 {{ $labels.instance }} 宕机" ``` 5. **可视化集成** 通过Grafana导入Prometheus数据源,使用预置仪表盘(如ID 8919展示Node Exporter指标)。 #### 四、核心优势 - **多维数据模型**:通过标签(Labels)灵活区分指标来源。 - **高效的存储与查询**:时间序列数据压缩存储,支持实时聚合计算。 - **动态服务发现**:适配云原生环境,自动发现Kubernetes集群中的Pod。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值