Prometheus-Remote Read Meets Streaming【翻译】
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Prometheus-Remote Read Meets Streaming【翻译】相关的知识,希望对你有一定的参考价值。
参考技术APrometheus新版本 2.13.0 的发布,他包含了许多bug fix和改进。你可以在这儿 查看变更 。这里有一个许多用户或项目十分期待的功能: chunked, streamed version of remote read API .
在本文中,我将深入介绍我们在远程协议中更改了哪些内容,更改的原因以及如何有效地使用它。
自从1.x版本,Prometheus有了与远程存储通过 remote API 交互的能力。
这个API允许第三方系统通过两种方法与metrics 数据交互:
这是将Prometheus数据放于第三方系统存储的最常见做法。在这种模式中,Prometheus周期性地向给定端点发送一批样本数据。
在3月份基于 WAL 的Remote write在可靠性和资源占用率上都得到了巨大的提升。值得一提的是 这里 所有的第三方存储都支持该种方式。
read方法不太常见。它是在 March 2017
添加的(服务端内部包含),自那以后没有看到显著的发展。
普罗米修斯2.13.0版本修复了Read API中已知的资源瓶颈。本文将重点讨论这些改进。
remote read的关键点是不经过PromQL计算的前提下直接查询Prometheus storage ( TSDB )。 他和 Querier 接口类似,用于从存储层获取数据。
这个特性允许对Prometheus采集到的时序数据进行访问, remote read主要使用场景如下:
远程读API暴露了一个简单的HTTP endpoint ,它期望数据格式如下:
通过这个协议,客户端可以通过 matchers 和 start 以及 end 的时间区间来获取到特定的时序数据
返回数据格式如下:
Remote read返回匹配的时序数据,包含raw数据(包含vaule和时间戳)
对于remote read有如下2个关键问题。它虽然很容易使用和理解,但是我们定义的protobuf格式的单个HTTP请求中没有streaming功能。其次,响应的是raw格式数据(float64值和int64时间戳),而不是TSDB存储的基于‘Chunk’的经过编码和压缩后的数据。
没有streaming的远程读取的server端逻辑是:
下面是Prometheus和Thanos Sidecar(remote read 客户端)在remote read请求期间内的内存使用情况:
值得注意的是,即便对于Prometheus原生Http接口的 query_range 方法而言, 查询10,000个series 也并不是一个好主意,因为你的浏览器也不希望获取,存储然后渲染数百兆字节的数据。此外,对于仪表板和呈现目的来说,拥有这么多数据也是不现实的,因为人不可能读取这么大量的数据。这就是为什么我们通常我们不会发起大于20个时序的查询请求。
虽然这样做很好,但是另外一种常规技术做法是通过聚合查询去获得聚合好的20个时间序列,但底层查询引擎必须通过上千个序列去计算响应(例如使用 aggregators 。这就是为什么像Thanos这样的系统,在其他数据中,使用TSDB数据从远程读取,通常情况下,请求很重。
理解Prometheus在查询时是如何迭代数据的对理解这个问题很有帮助。核心概念可以从 Querier 的 Select 方法返回的一个叫 SeriesSet 的类型中看出来。接口如下:
上面这一系列接口为进程提供了一种基于“流”的能力。我们不再需要预先计算包含样本的序列列表。使用这个接口,每个 SeriesSet.Next() 实现都可以根据需要获取序列。我们还可以通过 SeriesIterator.Next 动态地分别获取每个样本。
通过这个协议,Prometheus可以尽可能小的分配内存,因为PromQL引擎可以更优的对样本进行迭代,以计算出查询结果。TSDB以同样的方式实现SeriesSet,以一种最佳的方式从存储在文件系统中的块中一个接一个地获取序列,从而最小化分配。
这对 remote read API来说十分重要,因为我们可以以相同的调用形式来迭代式的向客户端发送单个时序中的一部分chunk形式的数据。因为protobuf原生没有分割消息数据的机制,所以我们 扩展了 proto定义来允许发送 一组小的protocol buffer消息 ,而不是单个巨大的消息体。我们把这种remote read模式称作 STREAMED_XOR_CHUNKS 而老的模式叫 SAMPLES 。扩展了protocol意味着Prometheus再也不需要缓冲整个响应了,他可以在调用 SeriesSet.Next 或者 SeriesIterator.Next 迭代时发送一个有序的独立帧,以尽可能的与下一个时序数据复用同一个内存页。
现在, STREAMED_XOR_CHUNKS 模式的响应是以下一组Protobuf消息(帧)
你可以发现消息帧不包含raw格式数据了。这是我们做的第二点提升:我们以chunk的形式发送消息样本(观看 这个视频 来了解更多关于chunk的知识)它与我们存储在TSDB中的chunk完全相同。
我们最终使用了以下服务端逻辑:
我们所有的设计都在 这里
与旧的解决方案相比,这种新方法的性能如何?
我们来将Prometheus 2.12.0 和 2.13.0 remote read特型进行对比。就如本文开头给出的初步结果,我用Prometheus做服务端,用Thanos的sidecar做远程读取的客户端。我使用 grpcurl 对Thanos sidecar执行gRPC调用来测试remote read。整个测试在我的笔记本((Lenovo X1 16GB, i7 8th)上docker中的k8s环境里进行。(使用 kind )
数据是人工生成的,表示高度动态的10,000个序列(最坏的情况)。
测试的详细结果请见 thanosbench repo
减少内存是我们解决方案的主要目标。在整个请求过程中,Prometheus的缓冲区大约为50MB,而Thanos只有少量的内存使用。多亏了流式Thanos gRPC StoreAPI, sidecar现在是一个非常简单的代理。
此外,我尝试了不同的时间范围和序列数量,但正如预期的那样,我一直看到Prometheus的分配最多为50MB,而Thanos的分配则没有。这证明无论你单个请求多少个样本,我们的remote read始终使用恒定的内存大小。分配内存的多少受请求数据数量的影响大大减少,无论你请求多少数据,他都始终分配相同的内存。
在并发性限制的帮助下,这使得针对用户流量进行容量规划变得更加容易。
在我的测试期间,CPU使用率也有所提高,使用的CPU时间减少了两倍。
通过streaming和更少的编码次数,我们同时还实现了减少remote read请求的响应延迟。
Remote read 8小时时间跨度包含10000个序列:
2h时间跨度:
在Prometheus和Thanos侧处理和序列化的时间上,除了低2.5倍的响应延迟外, stream版本的响应是及时的,而非 stream版本客户端延迟27s( real minus user time)。
Remote read以向后和向前兼容的方式进行了扩展。这要归功于protobuf和 accepted_response_types 被旧版本所忽略的字段,同时如果旧的客户端(假设采用 SAMPLES 模式的remote read)不支持 accepted_response_types 他也能正常工作。
remote read协议前后版本兼容方式:
为了使用新的基于streamed remote read的Prometheus v2.13.0,第三方系统必须将 accepted_response_types = [STREAMED_XOR_CHUNKS] 添加到请求中。
Prometheus就会用 ChunkedReadResponse 来替代老版本消息体。每个 ChunkedReadResponse 消息都符合varint大小和固定大小bigendian uint32用于CRC32 Castagnoli校验和。
对于go语音来说我们推荐使用 ChunkedReader 来直接读取流
注意, storage.remote.read-sample-limit 设置将在 STREAMED_XOR_CHUNKS. storage.remote.read-concurrent-limit 条件下不再起作用。
也提供了一个新的配置项 storage.remote.read-max-bytes-in-frame 来控制每个消息体的最大大小。建议默认为1MB,因为谷歌建议protobuf消息 不大于1MB .。
正如前面提到的, Thanos 因为这个特性收益颇丰。Streamed remote read 在 v0.7.0 被增加,因此,配合Prometheus 2.13.0 或更高版本,都将自动采用 streamed remote read 的形式。
Release 2.13.0引入了扩展的 remote read和Prometheus服务器端实现,然而,为了充分利用扩展的远程读协议的优势,目前还需要做一些事情:
综上所述,分块、流远程读取的主要好处是:
如果您有任何问题或反馈,一如既往,请随时在GitHub上提交问题或在邮件列表上提问。
以上是关于Prometheus-Remote Read Meets Streaming【翻译】的主要内容,如果未能解决你的问题,请参考以下文章
如何给oneindex网盘增加评论密码查看read me,头提示功能。
github+hexo搭建自己的博客网站注意事项(避免read.me,CNAME文件的覆盖,手动改github page的域名)