prometheus/tsdb 的源码阅读笔记 0x00

by admin on 2020年3月12日

近日伯克利 RISE Lab 开源了一个多数据流实时分布式分析系统
Confluo,它即是一个网络监控和诊断框架,也可以作为时序数据库和发布订阅消息系统。

在目前的 db-engines 时序数据库排名中, 第一位的
influxdb
和第七位的
prometheus
都是由 go 实现的.

澳门新葡亰平台官网 1

这次我打算阅读的源码是 promethus 的组件
prometheus/tsdb

源码地址:

时序数据库

澳门新葡亰平台官网,首先简单介绍一下, 时序数据库 (tsdb) 全称为 Time Series Database,
通常作为各类监测, 监控系统的核心组成部分. 通常需要极高的写入速度,
尽量经济的空间占用, 和尽可能高的批量数据查询效率.

除了上面提到的 influxdb 和 prometheus, 比较典型的还有 OpenTSDB, KairosDB
等.

当下,类似基于终端主机的网络监控系统、IoT
设备传感器程序等应用,其后端的服务器每秒都可以捕获数千万个数据点。这些数据被用于在线查询,实现可视化与监控,或者用于离线查询,进行故障分析和系统优化。这样的使用场景下,就需要实时监控和分析工具支持,这些工具通常支持高吞吐量数据提取、低延迟在线查询和低开销的离线查询。

时序数据库的存储

各类时序数据库的数据结构基本都以 tags , timestamp 和 value
这样一组概念为核心, 称为数据点, 类似一般数据库中的记录或条目概念.

查询大多基于时间戳, 并以 tags 作为辅助筛选项.

至于底层存储, 则有不同的流派, 一类是使用已有的成熟数据库产品, 比如
OpenTSDB 默认使用 HBase, KairosDB 基于 Cassandra 等;
另一类则采用自研的存储引擎, 比如 Influxdb 在 LSM
的基础上针对时序数据的特性开发了 TSM 存储引擎 tsm1, 而 prometheus/tsdb
则参考了 facebook 的 论文 Gorilla: A Fast, Scalable, In-Memory Time
Series
Database

虽然目前已经存在一些用于高吞吐量数据提取的数据结构,它们可以支持丰富的在线和离线查询,但是高吞吐量与查询能力目前来看还是互斥的。在从多个数据流提取数据时,查询需要更新多个数据结构,包括原始数据、聚合统计信息和物化视图。但是用于支持这些查询的数据结构往往具有较高的更新开销,而且无法维持大多数应用程序所需的数据提取速率。而另一方面,可以维持高数据提取速率的数据结构往往只支持非常简单的查询。

Facebook 的 Gorilla

Gorilla 的 最大特点, 是快和高压缩率.

facebook 总结了自身海量的 IT 系统监控数据得出以下结论

  1. 相邻数据点时间戳的差值相对固定, 即使变化也仅在一个很小的范围内浮动;
  2. 相邻数据点的值变化幅度也很小, 且有相当比例的值变化为0;
  3. 热点数据查询的频率远远超出非热点数据, 且越是近期的数据热度越高.

继而提出了 Gorilla 的存储设计:

  • 将一段时间的数据点存储在一个数据块内;
  • 数据块仅第一个点记录时间戳和值的绝对值,
    之后所有点仅记录其值的变化情况.

以传统时序数据结构中, 数据点的时间戳和值均记为 64 bit 的值, 共占用 16
Byte 为参照, Gorilla 疯狂地将每数据点的平均空间压缩到1.37 Byte,
与此同时满足了 fb 自身 700M 每分钟的数据点写入需求.

Gorilla 的缺点则在查询上, 对于目标时间点, 需要将其所在的数据块整个取出,
进行遍历.

因此, facebook 将其热点数据完全放在内存之中.

facebook 开源了 Gorilla 的 C++ 实现版本
beringei.

比较有趣的是,
国内最擅长多条腿走路的数据库及中间件巨头阿里在去年先后发布了自己的时序数据库产品
TimescaleDB

HiTSDB
. 前者基于 PostgreSQL, 而后者同样基于 Gorilla, 并声称数据点平均内存开销
2 Byte 以下, 且具备 10M/sec 的数据点写入能力. 算一算, 和 Gorilla
论文中的数字相差不多.

澳门新葡亰平台官网 2

prometheus/tsdb

prometheus/tsdb
是 prometheus 2.0 版本起使用的底层存储, 它的数据块编码也使用了 facebook
的 gorilla, 并具备了完整的持久化方案. 因此是我首先拿来参看的项目.

源码的阅读基于 commit
d45b59
, 将会分成多篇文章.

文章的数量, 篇幅和频率, 视乎我残存的悟性 😂.

以下是它的项目结构

├── Documentation
│   └── format
│       ├── chunks.md
│       ├── index.md
│       └── tombstones.md
├── LICENSE
├── README.md
├── block.go
├── block_test.go
├── chunkenc
│   ├── bstream.go
│   ├── chunk.go
│   ├── chunk_test.go
│   └── xor.go
├── chunks
│   └── chunks.go
├── cmd
│   └── tsdb
│       ├── Makefile
│       ├── README.md
│       └── main.go
├── compact.go
├── compact_test.go
├── db.go
├── db_test.go
├── encoding_helpers.go
├── fileutil
│   ├── dir_unix.go
│   ├── dir_windows.go
│   ├── fileutil.go
│   ├── mmap.go
│   ├── mmap_unix.go
│   ├── mmap_windows.go
│   ├── preallocate.go
│   ├── preallocate_darwin.go
│   ├── preallocate_linux.go
│   ├── preallocate_other.go
│   ├── sync.go
│   ├── sync_darwin.go
│   └── sync_linux.go
├── head.go
├── head_test.go
├── index
│   ├── encoding_helpers.go
│   ├── index.go
│   ├── index_test.go
│   ├── postings.go
│   └── postings_test.go
├── labels
│   ├── labels.go
│   ├── labels_test.go
│   └── selector.go
├── querier.go
├── querier_test.go
├── test
│   ├── conv_test.go
│   ├── hash_test.go
│   └── labels_test.go
├── testdata
│   └── 20kseries.json
├── testutil
│   └── testutil.go
├── tombstones.go
├── tombstones_test.go
├── tsdbutil
│   ├── buffer.go
│   └── buffer_test.go
├── wal.go
└── wal_test.go

Confluo
正是为了应对这种情况而产生的,它是一个致力于同时实现高吞吐量数据提取和富有表现力的离线/在线查询的系统。

参考文章

关于时序数据库及常见产品的解读, 可以参考云栖社区的一系列文章:

时间序列数据的存储和计算 –
概述

时间序列数据的存储和计算 –
开源时序数据库解析(一)

时间序列数据的存储和计算 –
开源时序数据库解析(二)

时间序列数据的存储和计算 –
开源时序数据库解析(三)

Confluo 性能强悍,支持:

  • 来自多个数据流的数百万个数据点的高吞吐量并发写入

  • 毫秒级的在线查询

  • 使用最少 CPU 资源的 ad-hoc 查询

不同场景下对 Confluo 进行性能测试,结果显示:

  • 作为一个网络监控和诊断框架,Confluo 能够在单核上以线路速率(10Gbps
    链路)执行数千个触发器和数十个过滤器。

  • 作为一个时序数据库,与其它诸如 CorfuDB、TimescaleDB 和 BTrDB
    等先进的时序数据库相比,Confluo 的吞吐量提高了 2 到 20
    倍,写入延迟降低了 2 至 10 倍,时间区间查询延迟降低了 5 至 20 倍。

  • 作为一个发布订阅消息系统,Confluo 的吐量是 Kafka 的 4 到 10 倍。

澳门新葡亰平台官网 3

更详细的分析:

(文/开源中国)    

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图