当前位置:网站首页>Prometheus Cortex使用Block存储时的相关问题
Prometheus Cortex使用Block存储时的相关问题
2022-04-23 06:01:00 【洒满阳光的午后】
架构概述(必看)
Prometheus Cortex架构概述(水平可扩展、高可用、多租户、长期存储)_洒满阳光的午后的博客-CSDN博客
使用Block存储的相关问题
使用Block存储时,需要运行额外两个服务,store-gateway和compactor。store-gateway负责查询block并被querier调用。compactor负责合并、去重block(因为replication factor的原因,同一序列会被N个Ingester存储N份,因此需要去重)。
Ingester会被本地每个租户创建一个TSDB,接收到的数据首先存在内存中,然后定期刷新到本地磁盘上(紧接着删除WAL),再然后本地磁盘上的block会被上传到存储中。可以通过-blocks-storage.tsdb.retention-period配置本地block的保存时间,因为querier和store-gateway需要时间来发现存储中新上传的block并下载meta.json/index。
Querier
Querier需要实时了解整个存储的概况以响应查询,为此有两种实现方式:
- 定期扫描bucket(默认)
- 定期下载bucket index
默认配置下(即禁用Bucket index),querier会在启动时扫描整个存储bucket来发现所有租户的block,并下载每个block的meta.jaon(其中有该block的起止时间)。在首次扫描期间,querier处于不可用状态。而在运行时,querier则会定期扫描bucket以发现新上传的block。querier使用meta.json来计算执行查询所需的block并从store-gateway获取数据。
如果启用了bucket index,则querier会在首次接收到某个租户的查询时下载biucket index,将其缓存在内存中并定期更新。Bucket index包含一个租户的block列表和待删除block列表,用于寻找查询所需的block集。使用该特性无需扫描bucket,因此querier会在启动后更快处于ready状态,并且降低对象存储的请求压力。
Querier会分析查询请求的起止时间计算出一个block列表,并向根据block列表计算出的store-gateway发送请求以获取所需数据。如果查询的时间范围覆盖-querier.query-ingesters-within的时间,则querier还会从Ingester内存中提取数据。提取完所有数据后,querier再使用PromQL引擎执行查询并将结果返回给客户端。
如果启用了block分片,则querier需要访问store-gateway的哈希环(通过参数 -store-gateway.sharding-ring.*)。如未启用分片,则通过-querier.store-gateway-addresses指定store-gaetway的地址列表。
生产环境中的querier强烈推荐使用缓存,目前仅支持元数据matadata缓存,元数据包括:
- 租户列表
- 每个租户的block列表
- block的meta.json
- block的deletion-mark.json
- 租户的bucket-index.json.gz
目前缓存后端仅支持memcached,可通过-blocks-storage.bucket-store.metadata-cache.backend、-blocks-storage.bucket-store.metadata-cache.memcached.*参数进行配置。
注意:querier和store-gateway应使用同一个memcached集群。
querier是无状态组件。
Store-gateway
store-gateway在获取bucket信息方式上与querier类似,他只关心自己分片(如启用)的block。在默认配置下,store-gateway除了meta.json外还会下载index-header到本地磁盘。如果启用bucket index,则只会下载bucket index。
关于分片和复制:
简单来说,如果启用了分片功能,则所有的store-gateway会组成一个哈希环,每个store-gateway(及后续N-1个store-gateway,N为replication-factor值)负责处理一个分片上的block。详见Blocks sharding and replication | Cortex (cortexmetrics.io)。可通过GET /store-gateway/ring查看环状态。
index-header
即使用HTTP范围请求(byte range requests)下载的原始block index中特定的一部分(Symbol table + Posting Offset Table)。
生产环境中的store-gateway强烈推荐使用缓存,目前支持如下缓存:
- Index cache(支持缓存于内存或memcached)
- Chunks cache(支持memchched)
- Metadata cache(支持memcached)
store-gateway是半有状态组件。
Compactor
Compactor是无状态组件,有两大作用:
将多个block(同一租户的)合并成一个更大更优的block,可以降低存储的使用量(数据去重、减小索引大小),并提高查询速度(需要查询的block数量变少,因而更快)。
保持所有租户的bucket index为最新状态。bucket index为querier、store-gateways和rulers所使用来发现存储中新的block。
如上图所见,compactor的压缩有两个过程:
- 垂直压缩:将同一时间范围内多个ingester上传的多个相同block压缩为一个,消除存储中由于replication_factor配置而产生的N个重复数据。
- 水平压缩:水平压缩在垂直压缩完成后触发,将相邻的多个2h block合并成一个。尽管合并后block中chunk大小并未改变,但可以显著减小index的大小,和store-gateway内存中的index-header的大小。
Compactor分片
即多个Compactor实例组成一个哈希环,分配不同的Compactor处理不同租户的block。同一租户的block同一时间只能由一个Compactor处理。详见:Compactor sharding
可通过 GET /compactor/ring查看哈希环状态。
Compactor在完成压缩后,会将原block删除。删除经历了两个过程:
- 软删除:通过在block中创建deletion-mark.json将其标记为待删除状态。
- 硬删除:在block被标记为待删除后的-compactor.deletion-delay时间,将block从storage中删除。
这么做的原因是期望给予querier和store-gateway足够的时间来发现压缩后的新block。
由于Compactor的处理过程需要下载原block和压缩后的block,因此需要考虑磁盘的使用量。假设max_compaction_range_blocks_size为某个租户在-compactor.block-ranges范围内所有block大小的总和(可根据bucket进行估算),那么compactor至少需要的磁盘空间大小min_disk_space_required为:
min_disk_space_required = compactor.compaction-concurrency * max_compaction_range_blocks_size * 2
Bucket index
前文多次提到的Bucket index,在此做一个阐述。
Bucket index是储存一个租户Blcok列表和Block删除标记的文件,文件本身存于后端对象存储中,由compactor组件定期更新。Bucket被querier、store-gateway、ruler所调用来获取存储中block情况,这些组件可通过参数-blocks-storage.bucket-store.bucket-index.enabled=true启用该功能。
使用Bucket index有如下好处:
- 减少querier和store-gateway对对象存储的API请求。
- querier和store-gateway无需使用存储的"list objects"API。
- querier可以快速启动,无需运行bucket初始化扫描。
bucket-index.json.gz文件包含:
- block列表,包括被标记为待删除的block
- block删除标记列表
- 最近更新时间
bucket index是如何保持更新的?
Compactor组件会定期扫描bucket,并上传更新后的bucket index到存储中。可以通过-compactor.cleanup-interval参数指定更新频率。尽管querier等组件的bucket index特性是可选的,但bucket index本身不会因为组件未启用该功能而不创建/更新。之所以这么设计,是为了保证不论何时用户启用了该功能,该文件都是存在的,查询结果的连续性得到保障。我们无需考虑更新此文件带来的资源开销。
Querier是如何使用bucket index的?
在查询时,querier和ruler会检查该租户的bucket index是否已经被加载在内存中,如果没有,则会从存储中下载并缓存到内存中。
由于Bucket index是一个小文件,因此现场下载并不会显著影响首次查询的性能,允许querier在不预下载每个租户的bucket index的情况下启动并运行。如果启用了metadata cache,则bucket index会在共享缓存中短暂保存,以减少下载延迟,并防止querier和ruler在短时间内多次下载相同的bucket index。
当bucket index被缓存在内存中后,后台进程会其进行定期更新。可配置如下两个参数:
- -blocks-storage.bucket-store.sync-interval,缓存的bucket index的更新频率。
- -blocks-storage.bucket-store.bucket-index.update-on-error-interval,如果下载bucket index失败,则短暂缓存失败状态一段时间,以避免影响后端存储。此选项配置当bucket index下载失败时,应以何种频率重试下载。
如果bucket index长时间未使用(由-blocks-storage.bucket-store.bucket-index.idle-timeout配置),例如当querier长时间未收到查询请求,那么querier就会卸载该索引,并停止更新。这尤其适用于querier分片时启用Shuffle Sharding | Cortex的场景(未不同租户分配不同querier,重新洗牌)。
querier和ruler在查询时会检查bucket index的实时性(通过文件中的更新时间),如果更新时间晚于-blocks-storage.bucket-store.bucket-index.max-stale-period,则查询失败。此中断是为了确保querier和ruler不会由于存储的陈旧试图而仅返回查询结果。
Store-gateway是如何使用bucket index的?
Store-gateway会在启动时及运行中定期获取自身分片租户的bucket index,将其作为存储中block的真实试图,从而避免了对存储的定期扫描。
一些tips
Ingester:节点需配置最大打开文件数,不低于65535。注意磁盘空间用量,取决于本地block保存时间。
Querier:启用缓存,启用bucket index,避免查询未压缩的block(详细配置方法见:Avoid querying non compacted blocks)
Store-gateway:启用缓存,启用bucket index,配置最大打开文件数不低于65535。
Compactor:确保compactor有足够的磁盘空间。Cortex 1.7.0后将将每个租户的block删除标记存储在了对象存储的markers/目录下,如果进行了版本升级,应确保删除标记的迁移只进行一次,在首次迁移完成后(日志中出现:msg="migrated block deletion marks to the global markers location")通过-compactor.block-deletion-marks-migration-enabled=false参数禁用。
Caching:推荐不同的缓存类型(metadata, index, chunks)使用不同的memcached集群,此项不必须。
其他
如何将Cortex集群从chunks存储切换到blocks存储?
Migrate Cortex cluster from chunks to blocks | Cortex (cortexmetrics.io)
如何将对象存储中的chunks转换为blocks?
Convert long-term storage from chunks to blocks | Cortex (cortexmetrics.io)
如何将Thanos和Prometheus中的数据迁移到Cortex?
Migrate the storage from Thanos and Prometheus | Cortex (cortexmetrics.io)
版权声明
本文为[洒满阳光的午后]所创,转载请带上原文链接,感谢
https://zhangrongjie.blog.csdn.net/article/details/121381430
边栏推荐
- 【MySQL基础篇】数据导出导入权限与local_infile参数
- [ES6 quick start]
- SQL学习|复杂查询
- 阅读笔记:Secure Federated Matrix Factorization
- 阅读笔记:Meta Matrix Factorization for Federated Rating Predictions
- redis 常见问题
- High performance gateway for interconnection between VPC and IDC based on dpdk
- Use the SED command to process text efficiently
- Basic concepts of database: OLTP / OLAP / HTAP, RPO / RTO, MPP
- 【代码解析(5)】Communication-Efficient Learning of Deep Networks from Decentralized Data
猜你喜欢
随机推荐
JS regular matching first assertion and last assertion
PHP background parsing after JQ serialization
CentOS8搭建PHP8.0.3运行环境
基于DPDK实现VPC和IDC间互联互通的高性能网关
The arithmetic square root of X in leetcode
阅读笔记:Meta Matrix Factorization for Federated Rating Predictions
ansible模块之include_tasks:为什么加了tags后导入的任务没有执行?
异常记录-5
Leak detection and vacancy filling (IV)
LeetCode刷题|368最大整除子集(动态规划)
Include of ansible module_ Tasks: why is the imported task not executed after adding tags?
[no steps in a small step to a thousand miles] Oracle Application derivative ora-01455 error reporting processing
Batch modify / batch update the value of a field in the database
JS handwriting compatibility event binding
Passerelle haute performance pour l'interconnexion entre VPC et IDC basée sur dpdk
Kids and COVID: why young immune systems are still on top
Ansible basic commands, roles, built-in variables and tests judgment
异常记录-20
通过源码探究@ModelAndView如何实现数据与页面的转发
MySQL【ACID+隔离级别+ redo log + undo log】