跳转至

Thanos 架构

Thanos 是一个基于 Prometheus 实现的监控方案,其主要设计目的是解决原生 Prometheus 上的痛点,并且做进一步的提升,主要的特性有:全局查询,高可用,动态拓展,长期存储

架构

Thanos 主要由如下几个特定功能的组件组成:

  • 边车组件(Sidecar):连接到 Prometheus,并把 Prometheus 暴露给查询网关(Querier/Query),以供实时查询,并且可以上传 Prometheus 数据到云存储,以供长期保存
  • 查询网关(Querier):实现 Prometheus API 以聚合来自底层组件(如边车组件 Sidecar,或是存储网关 Store Gateway)的数据
  • 存储网关(Store Gateway):将云存储中的数据内容暴露出来
  • 压缩器(Compactor):将云存储中的数据进行压缩和下采样和保留
  • 接收器(Receiver):从 Prometheus 的远程写入 WAL 接收数据,将其暴露出去或者上传到云存储
  • 规则组件(Ruler):根据 Thanos 中的数据评估记录和警报规则
  • 查询前端:实现 Prometheus 的 API,将其代理给 Query,同时缓存响应

从使用角度来看有两种方式去使用 Thanos,sidecar 模式和 receiver 模式。

sidecar 架构模式

Thanos Sidecar 组件需要和 Pormetheus 实例一起部署,用于代理 Thanos Querier 组件对本地 Prometheus 的数据读取,允许 Querier 使用通用、高效的 StoreAPI 查询 Prometheus 数据。第二是将 Prometheus 本地监控数据通过对象存储接口上传到对象存储中,这个上传是实时的,只要发现有新的监控数据保存到磁盘,会将这些监控数据上传至对象存储。

sidecar

Thanos Sidecar 组件在 Prometheus 的远程读 API 之上实现了 Thanos 的 Store API,这使得 Querier 可以将 Prometheus 服务器视为时间序列数据的另一个来源,而无需直接与它的 API 进行交互。

因为 Prometheus 每 2 小时生成一个时序数据块,Thanos Sidecar 会每隔 2 小时将这个块上传到一个对象存储桶中。这样 Prometheus 服务器就可以以相对较低的存储空间运行,同时通过对象存储提供历史数据,使得监控数据具有持久性和可查询性。但是这样并不意味着 Prometheus 可以完全无状态,因为如果 Prometheus 崩溃并重新启动,我们将失去大约 2 个小时的指标数据,所以 Prometheus 在实际运行中还是需要持久性磁盘的。

receiver 架构模式

Thanos Receiver 实现了 Prometheus 远程写 API,它构建在现有的 Prometheus TSDB 之上,并保持其实用性,同时通过长期存储、水平可伸缩性和下采样扩展其功能。Prometheus 实例被配置为连续地向它写入指标,然后 Thanos Receiver 默认每 2 小时将时间序列格式的监控数据块上传到一个对象存储的桶中。Thanos Receiver 同样暴露了 Store API,以便 Thanos Querier 可以实时查询接收到的指标。

receiver

这两种模式有各种的优缺点,具体使用哪种模式需要结合生产环境综合考虑。

工作流程

Thanos 是同时支持 Prometheus 读和写的远程存储方案,首先我们先看下 sidecar 模式下指标写入的整个流程:

  • 首先 Prometheus 从所采集服务的 metrics 接口抓取指标数据,同时根据自身所配置的 recording rules 定期对抓取到的指标数据进行评估,将结果以 TSDB 格式分块存储到本地,每个数据块的存储时长为 2 小时,且默认禁用了压缩功能。
  • 然后 sidecar 嗅探到 Prometheus 的数据存储目录生成了新的只读数据块时,会将该数据块上传到对象存储桶中做为长期历史数据保存,在上传时会将数据块中的 meta.json 进行修改添加 thanos 相关的字段,如 external_labels
  • rule 根据所配置的 recording rules 定期地向 query 发起查询获取评估所需的指标值,并将结果以 TSDB 格式分块存储到本地。每个数据块的存储时长为 2 小时,且默认禁用了压缩功能,每个数据块的 meta.json 也附带了 thanos 拓展的 external_lables 字段。当本地生成了新的只读数据块时,其自身会将该数据块上传到远端对象存储桶中做为长期历史数据保存。
  • compact 定期将对象存储中地数据块进行压缩和降准采样,进行压缩时数据块中的 truck 会进行合并,对应的 meta.json 中的 level 也会一同增长,每次压缩累加 1,初始值为 1。在进行降准采样时会创建新的数据块,根据采样步长从原有的数据块中抽取值存储到新的数据块中,在 meta.json 中记录 resolution 为采样步长。

读取指标的流程为:

  • 首先客户端通过 query APIquery 发起查询,query 将请求转换成 StoreAPI 发送到其他的 querysidecarrulestore 上。
  • sidecar 接收到来自于 query 发起的查询请求后将其转换成 query API 请求,发送给其绑定的 Prometheus,由 Prometheus 从本地读取数据并响应,返回短期的本地采集和评估数据。
  • rule 接收到来自于 query 发起的查询请求后直接从本地读取数据并响应,返回短期的本地评估数据。
  • store 接收到来自于 query 发起的查询请求后首先从对象存储桶中遍历数据块的 meta.json,根据其中记录的时间范围和标签先进行一次过滤。接下来从对象存储桶中读取数据块的 indexchunks 进行查询,部分查询频率较高的index 会被缓存下来,下次查询使用到时可以直接读取。最终返回长期的历史采集和评估指标。

对于发送报警的流程如下所示:

  • Prometheus 根据自身配置的 alerting 规则定期地对自身采集的指标进行评估,当告警条件满足的情况下发起告警到 Alertmanager 上。
  • rule 根据自身配置的 alerting 规则定期的向 query 发起查询请求获取评估所需的指标,当告警条件满足的情况下发起告警到 Alertmanager 上。
  • Alertmanager 接收到来自于 Prometheus 和 rule 的告警消息后进行分组合并后发出告警通知。

特性

Thanos 相比起原生的 Prometheus 具有以下的一些优势:

  • 统一查询入口——以 Querier 作为统一的查询入口,其自身实现了 Prometheus 的查询接口和 StoreAPI,可为其他的 Querier 提供查询服务,在查询时会从每个 Prometheus 实例的 SidecarStore Gateway 获取到指标数据。
  • 查询去重——每个数据块都会带有特定的集群标签, Querier 在做查询时会去除集群标签,将指标名称和标签一致的序列根据时间排序合并。虽然指标数据来自不同的采集源,但是只会响应一份结果而不是多份重复的结果。
  • 高空间利用率——每个 Prometheus 本身不存储长时间的数据,Sidecar 会将 Prometheus 已经持久化的数据块上传到对象存储中。Compactor 会定时将远端对象存储中的长期数据进行压缩,并且根据采样时长做清理,节约存储空间。
  • 高可用——Querier 是无状态服务,天生支持水平拓展和高可用。StoreRuleSidecar 是有状态服务,在多副本部署的情况下也支持高可用,不过会产生数据冗余,需要牺牲存储空间。
  • 存储长期数据——Prometheus 实例的 Sidecar 会将本地数据上传到远端对象存储中作为长期数据
  • 横向拓展——当 Prometheus 的指标采集压力过大时,可以创建新的 Prometheus 实例,将 scrape job 拆分给多个 Prometheus,Querier 从多个 Prometheus 查询汇聚结果,降低单个 Prometheus 的压力
  • 跨集群查询——需要合并多个集群的查询结果时,仅需要在每个集群的 Querier 之上再添加一层 Querier 即可,这样的层层嵌套,可以使得集群规模无限制拓展。