TOC

Prometheus存储

    Prometheus自己也内置了一个TSDB,而这个内置的TSDB其实经历过三个版本的迭代,Prometheus最早的时候用的都是v1.0的存储引擎,用的数据库是LevelDB,LevelDB是一个独立的第三方的独立项目,它就是一个TSDB数据库,但是LevelDB的性能不够高效,每秒钟只能接受50000个样本数据,这对于大规模系统来讲,确实是一个存在的问题;
    后来到了2.0时代,2.0还是用的LevelDB,但是Prometheus使用了Facebook的Gorilla压缩算法,极大的压缩了单个样本的大小,此时每秒可接收的样本提升到了80000个;
    但是这仍然只能适用一些中等规模的场景,而Prometheus的存储引擎到了v3.0时代,就弃用了LevelDB,自己重新研发了一个,这个重新研发的TSDB被当作一个独立的开源项目,他们是由Prometheus 2.0时代引入的,在单机上,每秒可处理的样本数,可达数百万级,目前默认的也都是这个TSDB系统;
存储逻辑
    Prometheus的TSDB存储逻辑大概是2小时为一个时间窗口,并存储为一个单独的block,block会进行压缩、合并历史数据块,随着压缩合并,其block数量会减少,block的大小并不固定,但是block最小会保存两个小时的数据,粒度不能再小了,我们可以指定一个block保存8个小时、4个小时,但是不能少于2个小时;
    下面有一个Head,它是用于保存当前块的,默认存储在内存中,所有的指标样本数据,都被Prometheus直接在内存中保存,但是为了确保这些样本数据能持久,不会因为宕机而丢失数据,所以Prometheus会对接收到的每一个样本在一个时间窗口内会试图基于内存映射的方式持久到磁盘上,这样即便宕机了,数据还是存在的,而后,这些数据的每一个样本会被以WAL的方式存储下来,类似Redis的AOF,以追加写的方式保存在WAL当中,而后每当一个时间窗口到达之后,Prometheus就会把数据合并,并生成一个新的block存储进来,因此数据就源源不断的存储进来,源源不断的压缩成block;
    所以每个Block都有一个单独的目录,因为每一个Block可能要保存的不单是样本数据,为了能快速查询,还有索引,查询的时候是根据索引查的,所以每个Block都有一个单独的目录,里面包含了该时间窗口所有的chunks、index、tombstones和meta.json;

chunks:用于保存时序数据,每个chunk的大小为512M,超出该大小则截断并创建为另一个chunk,各chunk以数据编号;
index:索引文件,它是Prometheus TSDB实现高效查询的基础,我们甚至可以通过MetricsName和Labels查找时序数据在chunk文件中的位置,索引文件会将指标名称和标签索引到样本数据的时间序列中;
tombstones:用于对数据进行软删除,以降低删除操作成本,删除的记录并保存于tombstones文件中,而读取时间序列,上的数据时,会基于tombstones进行过滤已删除的部分,在进行block合并的时候才会真正支持删除操作;
meta.json:block的元数据信息,这些元数据信息上block的合并、删除等操作的基础依赖;
[root@node1 ~]# ls /data/prometheus/
01F8XW62YVTRB7E4YM2332VMKY  01F8Y6FNT0GTMWC8M705M34SGD  01F8YD34NMKSB6NC0YA66897KR  chunks_head  lock  queries.active  wal
[root@node1 ~]# ls /data/prometheus/01F8XW62YVTRB7E4YM2332VMKY/
chunks  index  meta.json  tombstones
存储配置
    如果希望自己来配置TSDB的工作特性,有如下几个常用的参数;
--storage.tsdb.path:指定数据存储路径,默认为当前启动目录下的data;
--storage.tsdb.retention.time:样本数据在存储中保存的时长,超过该时长的数据就会被删除,默认为15d;
--storage.tsdb.retention.size:每个block的最大字节数(不包含WAL文件),支持B、KB、MB、GB、TB、PB和EB,例如512MB等;
--storage.tsdb.wal-compression:是否启用WAL的压缩机制,2.20以后的版本中默认为启用;
远程存储
    Prometheus本地可能只存储15天,30天,但是想长期存储, 比如不删了,有多少存多少,那么直接存储在Prometheus上这显然是不可行的,因为Prometheus是一个监控系统,监控才应该是它的核心功能,因而,Prometheus最好能使用外置的存储来存储数据,但是Prometheus自己也没开发其他的TSDB这样的存储设备,它可以直接支持借助于远端的第三方存储服务来存数据;
    而且远端的存储服务器,要使用Adapter来进行适配,Adapter对Prometheus来讲,我们可以通过Adapter使用PromQL将数据查询出来,再给它导入到另外一个存储系统当中去,读的时候,使用Adapter给它读出来再交给Prometheus的内存,然后显示给用户,这样处理,所以对Prometheus而言,它的写和读,是分开操作的,写可以写到一个存储上,读也可以从另外一个存储读;
Prometheus集群
    建立起多个Prometheus Server同时工作,共同收集同一组指标,但是这有几个问题,存在数据不一致的可能性,同时不支持数据长期存储,仅适用于小规模的系统;

发表回复

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