Prometheus TSDB (Part 3): Memory Mapping of Head Chunks from Disk

本文译自Ganesh Vernekar 的 prometheus-tsdb-mmapping-head-chunks-from-disk。

文章目录

  • Prometheus TSDB (Part 3): Memory Mapping of Head Chunks from Disk
  • Introduction
  • Writing these chunks
  • Format on disk
    • The File
    • Chunks
  • Reading these chunks
  • Replaying on startup
  • Enhancements that this brings in
    • Memory savings
    • Faster startup
  • Garbage collection
  • Code reference

Introduction

在TSDB系列博客的 第一部分,我提到过一次“当chunk满的时候”,它会被刷到磁盘并memory-mapped,这有助于减少Head Block的内存占用,同时也有助于加快在第二部分中提到的WAL重播的速度。在本篇博客中,我们来更深入的讨论这部分的设计。

Writing these chunks

回顾第一部分,当chunk满的时候,我们会切出一个新的chunk,老的chunks将成为不可变的chunk,并且只能读取数据(黄色块为老的chunk,红色块为新切出的chunk)。

老的chunk我们不再存储在内存中,而是刷到磁盘上并存储一个引用,用于后续访问它。

这个被刷到磁盘的chunk就是memory-mapped chunk。此处“不可变”是一个非常重要的特性,因为如果要重写这些已压缩的chunk,对所有Sample而言效率太低。

Format on disk

可以在Github中找到。

The File

这些chunks存储在chunks_head目录中,其文件序列名和WAL中的类似。如下:

data
├── chunks_head
|   ├── 000001
|   └── 000002
└── wal├── checkpoint.000003|   ├── 000000|   └── 000001├── 000004└── 000005

这些文件的最大大小为128MiB,我们来详细看一下每个文件的结构,单个文件中包含一个8Byte的头。

┌──────────────────────────────┐
│  magic(0x0130BC91) <4 byte>  │
├──────────────────────────────┤
│    version(1) <1 byte>       │
├──────────────────────────────┤
│    padding(0) <3 byte>       │
├──────────────────────────────┤
│ ┌──────────────────────────┐ │
│ │         Chunk 1          │ │
│ ├──────────────────────────┤ │
│ │          ...             │ │
│ ├──────────────────────────┤ │
│ │         Chunk N          │ │
│ └──────────────────────────┘ │
└──────────────────────────────┘

Magic Number是用于标识这类文件类型为memory-mapped chunks文件,Chunk Format告诉我们用什么方式来解码这个文件,padding用于后续的扩展。

Chunks

单个Chunk格式如下所示

┌─────────────────────┬───────────────────────┬───────────────────────┬───────────────────┬───────────────┬──────────────┬────────────────┐
| series ref <8 byte> | mint <8 byte, uint64> | maxt <8 byte, uint64> | encoding <1 byte> | len <uvarint> | data <bytes> │ CRC32 <4 byte> │
└─────────────────────┴───────────────────────┴───────────────────────┴───────────────────┴───────────────┴──────────────┴────────────────┘

series ref我们在第二部分讨论过,是对Seires的引用,可以用来关联访问内存中的Seires。mintmaxt是chunk中可以找到的Sample数据的最小和最大时间戳。encodnig是用于压缩chunk的算法。len是从此处开始的字节数,而data是实际压缩的chunk的字节数据。

CRC32是上述chunk内容的校验和,用于验证数据的完整性。

Reading these chunks

对于所有的chunk,Head Block中都会存储它的mintmaxt以及引用。

引用占8个字节,前四个字节指明chunk所在的文件序列名,后四个字节指明该chunk在这个文件的offset(也就是seires ref所在字节)。如果chunk在00093文件,并且series ref在offset1234处,则该chunk的引用为(93 << 32 | 1234)

我们将mintmaxt存储在Head中,以便我们在筛选时无需查询磁盘。当我们必须要访问chunk时,我们使用引用来访问编码和chunk数据。

在代码中,该文件看起来像一个字节切片(每个切片对应一个文件),OS将内存中的切片映射到磁盘上,在索引处获得chunk数据。从磁盘进行memory-mapping是OS的特性,它仅将磁盘的一部分取到内存中,而非整个文件。

Replaying on startup

在第二部分中,我们讨论了WAL的重播,我们通过重播每个独立的Sample来重新构建压缩后的chunk。现在我们在磁盘上已经有了完整的压缩后的chunk,因此我们无需重新创建这些chunk,只需要重新创建那些没有满的chunk。现在有了这些来此磁盘的memory-mapped chunk,重播会发生如下动作。

在开始的时候,我们首先在迭代chunk_head目录下的所有chunks,并且构造一个map,结构是series ref -> [chunk引用的列表]

然后我们就按照第二部分的描述来进行WAL重播,少量调整如下:

  • 当我们遇到Seires时,在创建完Seires后,我们会在上述map中查找引用,如果存在memory-mapped chunk,那会进行关联;
  • 当遇到Sample时,如果该Sample相关联的Seires存在memory-mapped chunk,并且该Sample的时间戳在这些chunk的range内,则直接跳过该Sample。如果不在范围内,则将这个样本加入Head中;

Enhancements that this brings in

当我们可以通过内存型的chunk和WAL来存储数据是,这种增加复杂性的memory-mapped会给我们带来些什么呢?该特性我们在2020年添加,所以我们看看它带来了什么。

Memory savings

如果我们必须将chunk存储在内存中,它可能需要占用120到200字节(甚至更多,取决于样本的可压缩性)。而现在被替换为24字节(chunk引用、mintmaxt)。

虽然这听起来好像减少了80%-90%的内存,但实际情况有所不同,Head需要存储更多的东西,比如内存索引、所有符号(标签值)等,以及TSDB的其它部分。

真是的情况是,我们可以看到内存占用减少了15%-50%,这取决于采样速度和创建新Seires的速度。另一件需要注意的事情是,如果运行的一些查询需要大量使用这些chunk,那它们仍然需要加载到内存运行,所以这并不是峰值内存使用量的绝对减少。

Faster startup

WAL的重播是启动时最慢的部分,从磁盘解码WAL记录以及通过单个Sample来重建压缩chunk的过程是最慢的两个部分。而memory-mapped的迭代则相对较快。

我们无法避免对Record进行解码,因为我们需要进行检查。如你在上述描述中看到的,我们跳过了那些在memory-mapped chunk范围内的样本,这里我们避免了重新创建那些完整的压缩后的chunk,这被认为可以减少15%-30%的启动时间。

Garbage collection

内存中的垃圾回收发生在Head清空的期间,它只是丢弃了在清空时间T之前的chunk的引用,但是文件仍然存在于磁盘上。和WAL的segment一样,我们还需要定期删除旧的memory-mapped文件。

// …阅读源码后补充

Code reference

tsdb/chunks/head_chunks.go包含写chunks到磁盘、通过引用访问chunk、清空、处理文件、迭代chunks的所有实现。

tsdb/head.go将其作为黑盒使用,用于memory-mapped。

Prometheus TSDB (Part 3): Memory Mapping of Head Chunks from Disk相关推荐

  1. 一个Linux驱动:Simple - REALLY simple memory mapping demonstration.

    来源:LINUX设备驱动程序第三版配套源码 Table of Contents simple.c simple_load simple_unload Makefile simple.c /** Sim ...

  2. Glide java.io.IOException(File unsuitable for memory mapping)

    异常信息 03-06 14:43:26.656 W/Glide ( 852): class com.bumptech.glide.load.engine.GlideException: Failed ...

  3. Vulkan系列教程—VMA教程(三)—内存映射(Memory Mapping)

    文章目录 前言 一.Mapping Functions 二.Persistently mapped memory(永久Mapping) 三.Cache flush and invalidate 四.检 ...

  4. Prometheus TSDB

    TSDB 概述: Head: 数据库的内存部分 Block: 磁盘上持久块,是不变的 WAL: 预写日志系统 M-map: 磁盘及内存映射 粉红色框是传入的样品,样品先进入Head中存留一会,然后到磁 ...

  5. Prometheus TSDB存储原理

    Python微信订餐小程序课程视频 https://blog.csdn.net/m0_56069948/article/details/122285951 Python实战量化交易理财系统 https ...

  6. prometheus/tsdb压缩流程

    tsdb/compact.go populateBlock 1. indexr,chunkr,tombsr读blocks信息到内存 2.写symbol到index for sumbols.Next() ...

  7. Uncontrolled memory mapping in camera driver (CVE-2013-2595)

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/hu3167343/article/details/34434235 /* 本文章由 莫灰灰 编写,转 ...

  8. 世嘉土星系统memory mapping システムの使用するメモリのマッピングについて

    世嘉土星在设计的时候参考了linux,但由于导入工具链过程中发现,由于增加土星的MMU,内存地址管理器,会显著增加成本,且使用OS会导致技能performance的下降,所以自己通过链接器DLT方式, ...

  9. 内存缓存(from memory cache)和硬盘缓存(from disk cache) 的区别

    引言 ?命中强制缓存时,资源会显示 from memory cache or from disk cache 两者的区别 内存缓存(from memory cache) 内存缓存具有两个特点,分别是快 ...

最新文章

  1. 10w行级别数据的Excel导入优化记录
  2. Cflow使用具体解释
  3. 攻防世界-web-unfinish-从0到1的解题历程writeup
  4. 第1章 计算机基础知识习题答案,职称计算机基础知识习题第一章
  5. C++ 动态内存管理:c/c++的动态内存管理,new/delete,operator new/delete,placement-new, 内存泄漏
  6. Android中保存数据的三种方法
  7. 【clickhouse】clickhouse查询语句之simple
  8. cvi中c语言只保留两位小数,保留两位小数,但要求只显示一位小数,怎么实现?...
  9. 前端 常用css总结
  10. 手机屏幕宽高像素计算_国内手机厂商纷纷支持,三星传感器终成正果!索尼还能雄起吗?...
  11. win10个人壁纸默认保存位置
  12. CentOS6.7安装Python3.4
  13. 20155209 林虹宇 Exp3 免杀原理与实践
  14. FidMTF: An MTF Estimator (FidMTF:一种MTF估计方法)
  15. 重磅推出:2019中国开源年度报告
  16. SpringBoot 自动配置初探
  17. Ubuntu 21.04(arm64) 基于sanp安装Nextcloud,挂载本地硬盘
  18. 春季儿童吃什么有助于长高,3款适合孩子长高的食谱做法,学起来
  19. Python编程求:一个球从100m高度自由落下,每次落地后反跳回原高度的一半,再落下,反弹,求在第十次落地时,共经过多少米,第十次反弹多高
  20. 模仿是学习的最佳途径

热门文章

  1. DHCP Option43配置
  2. 张高兴的 Windows 10 IoT 开发笔记:使用 ADS1115 读取模拟信号
  3. 定远化工学校计算机专业数学达标分,定远化工学校2019高考成绩喜报、本科上线人数情况...
  4. 如何才可以顺利的打开加密的pdf文件
  5. [项目管理-32]:项目经理六阶段职业成长之路: 达克效应=>短板理论=>刻意练习=>长版板子理论=>精进=>布道
  6. oracle数据库常见故障及灾难情况分析
  7. Paxos算法P2c是如何满足P2b的?
  8. java jmap_Java性能测试之jmap
  9. 2022-2027年中国竹纤维毛巾行业市场全景评估及发展战略规划报告
  10. win7电脑一开机就蓝屏怎么回事?常见蓝屏代码