Prometheus TSDB分析
Prometheus TSDB分析
概述
Prometheus是著名开源监控项目,其监控任务调度给具体的服务器,该服务器到目标上抓取监控数据,然后保存在本地的TSDB中。自定义强大的PromQL语言查询实时和历史时序数据,支持丰富的查询组合。
Prometheus 1.0版本的TSDB(V2存储引擎)基于LevelDB,并且使用了和Facebook Gorilla一样的压缩算法,能够将16个字节的数据点压缩到平均1.37个字节。
Prometheus 2.0版本引入了全新的V3存储引擎,提供了更高的写入和查询性能。本文主要分析该存储引擎设计思路。
设计思路
Prometheus将Timeseries数据按2小时一个block进行存储。每个block由一个目录组成,该目录里包含:一个或者多个chunk文件(保存timeseries数据)、一个metadata文件、一个index文件(通过metric name和labels查找timeseries数据在chunk文件的位置)。最新写入的数据保存在内存block中,达到2小时后写入磁盘。为了防止程序崩溃导致数据丢失,实现了WAL(write-ahead-log)机制,将timeseries原始数据追加写入log中进行持久化。删除timeseries时,删除条目会记录在独立的tombstone文件中,而不是立即从chunk文件删除。
这些2小时的block会在后台压缩成更大的block,数据压缩合并成更高level的block文件后删除低level的block文件。这个和leveldb、rocksdb等LSM树的思路一致。
这些设计和Gorilla的设计高度相似,所以Prometheus几乎就是等于一个缓存TSDB。它本地存储的特点决定了它不能用于long-term数据存储,只能用于短期窗口的timeseries数据保存和查询,并且不具有高可用性(宕机会导致历史数据无法读取)。
Prometheus本地存储的局限性,所以它提供了API接口用于和long-term存储集成,将数据保存到远程TSDB上。该API接口使用自定义的protocol buffer over HTTP并且并不稳定,后续考虑切换为gRPC。
磁盘文件结构
内存中的block
内存中的block数据未刷盘时,block目录下面主要保存wal文件。
./data/01BKGV7JBM69T2G1BGBGM6KB12
./data/01BKGV7JBM69T2G1BGBGM6KB12/meta.json
./data/01BKGV7JBM69T2G1BGBGM6KB12/wal/000002
./data/01BKGV7JBM69T2G1BGBGM6KB12/wal/000001
持久化的block
持久化的block目录下wal文件被删除,timeseries数据保存在chunk文件里。index用于索引timeseries在wal文件里的位置。
./data/01BKGV7JC0RY8A6MACW02A2PJD
./data/01BKGV7JC0RY8A6MACW02A2PJD/meta.json
./data/01BKGV7JC0RY8A6MACW02A2PJD/index
./data/01BKGV7JC0RY8A6MACW02A2PJD/chunks
./data/01BKGV7JC0RY8A6MACW02A2PJD/chunks/000001
./data/01BKGV7JC0RY8A6MACW02A2PJD/tombstones
mmap
使用mmap读取压缩合并后的大文件(不占用太多句柄),建立进程虚拟地址和文件偏移的映射关系,只有在查询读取对应的位置时才将数据真正读到物理内存。绕过文件系统page cache,减少了一次数据拷贝。查询结束后,对应内存由Linux系统根据内存压力情况自动进行回收,在回收之前可用于下一次查询命中。因此使用mmap自动管理查询所需的的内存缓存,具有管理简单,处理高效的优势。
从这里也可以看出,它并不是完全基于内存的TSDB,和Gorilla的区别在于查询历史数据需要读取磁盘文件。
Compaction
Compaction主要操作包括合并block、删除过期数据、重构chunk数据。其中合并多个block成为更大的block,可以有效减少block个数,当查询覆盖的时间范围较长时,避免需要合并很多block的查询结果。
为提高删除效率,删除时序数据时,会记录删除的位置,只有block所有数据都需要删除时,才将block整个目录删除。因此block合并的大小也需要进行限制,避免保留了过多已删除空间(额外的空间占用)。比较好的方法是根据数据保留时长,按百分比(如10%)计算block的最大时长。
Inverted Index
Inverted Index(倒排索引)基于其内容的子集提供数据项的快速查找。简而言之,我可以查看所有标签为app=“nginx”的数据,而不必遍历每一个timeseries,并检查是否包含该标签。
为此,每个时间序列key被分配一个唯一的ID,通过它可以在恒定的时间内检索,在这种情况下,ID就是正向索引。
举个栗子:如ID为9,10,29的series包含label app="nginx",则lable "nginx"的倒排索引为[9,10,29]用于快速查询包含该label的series。
性能
在文章Writing a Time Series Database from Scratch里,作者给出了benchmark测试结果为Macbook Pro上写入达到2000万每秒。这个数据比Gorilla论文中的目标7亿次写入每分钟(1000千多万每秒)提供了更高的单机性能。
参考
Writing a Time Series Database from Scratch
Prometheus官方介绍
时间序列数据的存储和计算 - 开源时序数据库解析(四)
Prometheus TSDB分析的更多相关文章
- Prometheus TSDB存储原理
Prometheus 包含一个存储在本地磁盘的时间序列数据库,同时也支持与远程存储系统集成,比如grafana cloud 提供的免费云存储API,只需将remote_write接口信息填写在Prom ...
- 使用loki+ mtail + grafana + prometheus server分析应用问题
loki 是一个方便的类似prometheus 的log 系统,mtail 是一个方便的日志提取工具, 可以暴露为http 服务——支持导出prometheus metrics 环境准备 docker ...
- 微服务监控之三:Prometheus + Grafana Spring Boot 应用可视化监控
一.Springboot增加Prometheus 1.Spring Boot 应用暴露监控指标,添加如下依赖 <dependency> <groupId>org.springf ...
- Prometheus中使用的告警规则
参考网站:https://awesome-prometheus-alerts.grep.to/rules 这个网站上有好多常用软件的告警规则,但是有些并不一定实用,有些使用起来会有错误,这里就把这些都 ...
- Prometheus自身的监控告警规则
1.先在 Prometheus 主程序目录下创建rules目录,然后在该目录下创建 prometheus-test.yml文件,内容如下: 内容很多,可以根据实际情况进行调整. 规则参考网址:http ...
- kubernetes 1.15.1 高可用部署 -- 从零开始
这是一本书!!! 一本写我在容器生态圈的所学!!! 重点先知: 1. centos 7.6安装优化 2. k8s 1.15.1 高可用部署 3. 网络插件calico 4. dashboard 插件 ...
- PromQL全解析
PromQL(Prometheus Query Language)为Prometheus tsdb的查询语言.是结合grafana进行数据展示和告警规则的配置的关键部分. 本文默认您已了解Promet ...
- 使用 Ansible 快速部署 HBase 集群
背景 出于数据安全的考虑,自研了一个低成本的时序数据存储系统,用于存储历史行情数据. 系统借鉴了 InfluxDB 的列存与压缩策略,并基于 HBase 实现了海量存储能力. 由于运维同事缺乏 Had ...
- Grafana Mimir:支持乱序的指标采集
Grafana Mimir:支持乱序的指标采集 译自:New in Grafana Mimir: Introducing out-of-order sample ingestion 很早之前在使用th ...
随机推荐
- T-SQL查询进阶--理解SQL Server中索引的概念,原理
简介 在SQL Server中,索引是一种增强式的存在,这意味着,即使没有索引,sql server仍然可以实现应有的功能,但索引可以在大多数情况下提升查询性能,在OLAP(On line Trans ...
- 什么时候调用dealloc
什么时候回调用dealloc? 1.这个类被release的时候会被调用: 2.这个对象的retain count为0的时候会被调用: 3.或者说一个对象或者类被置为nil的时候:
- 原码、反码、补码及位操作符,C语言位操作
计算机中的所有数据均是以二进制形式存储和处理的.所谓位操作就是直接把计算机中的二进制数进行操作,无须进行数据形式的转换,故处理速度较快. 1.原码.反码和补码 位(bit) 是计算机中处理数据的最小单 ...
- 题解 UVA10212 【The Last Non-zero Digit.】
题目链接 这题在学长讲完之后和看完题解之后才明白函数怎么构造. 这题构造一个$f(n)$ $f(n)$ $=$ $n$除以 $2^{a}$ $*$ $5^{b}$ ,$a$ , $b$ 分别是 $n$ ...
- CAP理论中的P到底是个什么意思
在CAP理论中,C代表一致性,A代表可用性(在一定时间内,用户的请求都会得到应答),P代表分区容错.这里分区容错到底是指数据上的多个备份还是说其它的 ? 我感觉分布式系统中,CAP理论应该是C和A存在 ...
- php 大文件读取
当你需要处理一个5G的文件里面的数据时,你会怎么做,将文件里面的内容全部读取到一个数组里面去? 显然这种做法对小文件是没有问题的,但是对于大文件还是不行的 这时就需要用到 yield 了 ,注意这是 ...
- Linux管理命令
管理命令 用户管理: useradd, userdel, usermod, passwd, chsh, chfn, finger, id, chage 组管理: groupadd, groupdel, ...
- 181114socke编程
一.Socket Families 地址簇 socket.AF_UNIX socket.AF_INET socket.AF_INET6 二.Socker Types socket.SOCK_STREA ...
- 20165224 陆艺杰 Exp3 免杀原理与实践
杀软是如何检测出恶意代码的? 识别代码特征码 监测像后门的行为 (2)免杀是做什么? 让后面程序不被安全软件发现 (3)免杀的基本方法有哪些? 多方式编码 半手工shellcode编程 完全自己写没有 ...
- 【转】LAMBDAFICATOR: Crossing the gap from imperative to functional programming through refactorings
Link:http://refactoring.info/tools/LambdaFicator/ Problem Description Java 8 will support lambda exp ...