Promethues TSDB (Part 1): The Head Block

Promethues TSDB (Part 1): The Head Block

本文译自Ganesh Vernekar 的 prometheus-tsdb-the-head-block

Introduction

Promethues 2.0 已经启动三年时间,除Fabian的 Writing a Time Series Database from Scratch
之外,没有太多资料是介绍Prometheus TSDB部分的,而Prometheus官方的 Formt 的文档也更多是面向开发者的。

Promtheus的TSDB近期吸引了很多新的贡献者,但是因为资料的缺失,导致大家对TSDB的理解依然是一大痛点。因为,我计划通过一系列的博客来介绍TSDB的工作原理,同时也附上一些相关的代码引用,以便于Contributors理解TSDB的原理。

在本篇博客中,我主要讨论TSDB中的in-memory部分 - Head Block,在后续的博客,我还会再继续深入的介绍其它的组件,如WAL&CheckPointing、Chunk memory-mapping的设计、压缩、持久化Block、索引,以及Block快照等。

Prologue

Fabian的博客对于理解数据模型、核心概念、TSDB的设计等是很好的阅读材料,同时他也在2017的 PromCon 上发表过有关于此的演讲,我强烈建议先阅读下他的博客或观看演讲视频,以对这些概念有初步的理解。

在本篇博客里所讲解的关于样本的生命周期相关内容,在我 KubeCon 的演讲中也有介绍。

Small Overview of TSDB

在这里插入图片描述
如上图所示,Head Block(黄色块)是in-memory的部分,而Block N(灰色块)则是持久化到磁盘上的不可变的部分。我们通过Write-Ahead-Log(WAL,即棕色块)来实现持久化的写入。对于一个待插入的样本数据(粉色块),首先会进入Head Block,并在内存中驻留一段时间,之后很快就会被刷新到磁盘以及memory-mapped(蓝色块)中。之后到某个确定的时刻时,memory-mapped Chunk或in-memory Chunk中的数据就会“变老”,这时它们就会被作为一个持久化的块存储到磁盘上。更早之前的多个Block会被合并,最终如果这些Block超过了保留周期的,则会被删除。

Life Of a Sample in the Head

如下的所有论述都是讨论单个时序,对所有时序也都是同样的道理。
在这里插入图片描述
样本数据都是存储在一个名为“Chunk”的压缩单元中,当一个样本数据到达时,它会被当前活跃的Chunk接收(红色块),这也是唯一我们可以写入数据的单元。

当往Chunk提交样本数据的时候,出于持久化的目的,我们也会通过Write-Ahead-Log(WAL,即棕色块)的方式将其落盘,这意味着即便机器突然Crash,我们也可以通过WAL的数据来恢复in-memory的数据。后续我会在别的博客中单独讲解WAL的内容。

在这里插入图片描述
当Chunk被塞满数据时(默认120个样本),或者其已经到达Chunk/Block的最大时间窗口(默认2小时,后续称之为chunkRange),一个新的Chunk会被切分出来,并且当前这个老的Chunk会被打上“full”的标签。我们暂时假设我们抓取样本数据的间隔是15s,所以120个样本大约30分钟就能抓满。上面编号为1的“full Chunk”(黄色块)代表老的Chunk,红色块则是新切分出来的Chunk。

在这里插入图片描述
从Prometheus v2.19.0开始,我们不再在内存中存储所有Chunk了,当新的Chunk切分出来时,老的Chunk就会很快的写入磁盘,memory-mapped中只会存储一个引用。通过memory-mapping,我们可以通过这个引用动态的将Chunk加载到内存中。
在这里插入图片描述
同理,当不断有新的样本数据采集进来的时候,新的Chunk也会持续不断的被切分出来。
在这里插入图片描述
然后它们会被刷到磁盘并memory-mapped。
在这里插入图片描述
经过一段时间后,Head Block就会如上图所示,如果我们考虑当新的Chunk(红色块)快满的情况的话,那此时存储了块3个小时的数据(6个Chunk,每个Chunk按30分钟采满计算)。
在这里插入图片描述
当Head Block中的数据超过chunkRange*3/2的范围后,最早的chunkRange(两小时)周期内的数据将被压缩存储到持久化的Block中。如果你有注意WAL(棕色快)的变化,则会发现此时WAL的部分数据会被截断,并且一个“checkpoint”会被创建(未在此图中示意)。我会在后续的博客中详细介绍checkpointing、WAL截断、压缩、持久化Block以及索引等机制。

这种采集样本、memory-mapping、压缩到持久化Block的过程一直在循环持续,这也构成了Head Block的基本功能。

Few more things to note/understand

Where is the index?

作为倒排索引的形式存储在内存中,在Fabian的博客中有阐述整体的概念。当Head Block触发持久化到磁盘时,Head Block中老的Chunk会被截断,此时索引的垃圾回收也会将Head中不存在的数据的索引移除。

Handling Restarts

当TSDB需要重启时(正常或突发情况),它通过磁盘上的memory-mapped Chunks以及WAL来获取数据和时间,并在内存中重构索引和Chunk。

Code reference

tsdb/db.go TSDB的整体功能。
此外与本篇博客相关性较高的是tsdb/head.go,包含in-memory Chunks的主要逻辑,可以看做WAL和memory-mapping的黑盒。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值