• 剖析Prometheus的内部存储机制


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

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

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

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

    http_requests_total{status="200",method="GET"}
    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核 块编码耗时
    1 3.3 1.6 2.9s
    2 1.3 2.4 4.9s

    V0 结构

    V1 结构

    V2 结构

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

    以上内容是根据Prometheus官方人员的一份PPT摘取,原文件在此:https://files.cnblogs.com/files/vovlie/copyofprometheusstorage1-160127133731.pdf

  • 相关阅读:
    SQLSERVER 2008 编辑所有或者任意行
    在SQL2008和2012里面怎么让显示全部行和编辑 全部而不是200和1000
    sql server 提取汉字/数字/字母的方法
    [再寄小读者之数学篇](2014-05-12 曲线的弧长计算)
    [复变函数]第23堂课 6.2 用留数定理计算实积分 (续)
    [再寄小读者之数学篇](2014-04-23 行列式的导数)
    [再寄小读者之数学篇](2014-04-22 平方差公式在矩阵中的表达)
    康乐不风流之爱解题的pde灌水王张祖锦
    [复变函数]第22堂课 6.2 用留数定理计算实积分
    [Tex学习笔记]数学公式再次测试
  • 原文地址:https://www.cnblogs.com/vovlie/p/7709312.html
Copyright © 2020-2023  润新知