Prometheus水平扩展Cortex的架构分析

Cortex由Weaveworks建立,是一个开放源码的时间序列数据库和监视系统,用于应用程序和微服务。基于Prometheus,Cortex增长了水平缩放和几乎无限的数据保留。
<!--more-->前端

Cortex的架构图

Architecture

Cortex中的工做的流程以下:
cortex数据库

Prometheus 的做用

Prometheus 实例从各个目标中抓取样本,而后将他们推送到 Cortex 集群(直接远程写入 API)。API 自己在 Http 请求主体内发出批处理的 Snappy 压缩 Protocol Buffer (协议缓冲区)消息 PUT.后端

Cortex 要求每一个 HTTP 请求都带有 Header 里面有 X-Scope-OrgID 字段,这是Cortex里面的租户ID.请求认证以及受权则是由反向代理 Ngnix 来进行。缓存

咱们能够对 Prometheus 进行缩放或者分片操做:服务器

Scaling Prometheus
架构

Sharding Prometheus
app

Storage

Cortex 当前支持两个存储引擎来存储和查询时间序列:负载均衡

  • Chunks(大快存储), 默认的存储引擎,稳定;
  • Blocks (块存储),实验性,这个存储的方式相似与 HDFS中的Block存储

Chunks 存储

这种存储形式是将咱们的单个的时间序列分别存储到 Chunk 的单独的对象里面去。每块会包含一个给定的时间段内的样本(默认是 12 h), 而后能够按照时间范围和标签对 Chunks 进行索引。dom

目前咱们使用的快存储技术是: Apache Cassandra微服务

在内部,对 Chunks Storge 的访问,依赖于 Chunks Store 的统一的接口,和其余的 Cortex的组件不同的是,这个独立的接口不是一个单独的服务,而是一个嵌入在须要访问长期存储的服务中的库:ingester , querier , ruler .

目前Cortex 里面对这个 Chunk 和 index 已经版本化,这也就意味着咱们能够升级咱们的集群去利用新的功能。同时,该策略可更改存储格式,而无需任何停机时间或复杂的过程便可重写存储的数据。

Block 存储

这种存储方式目前还在测试阶段,它是基于 Prometheus TSDB : 将每一个租户的时间序列存储到本身的 TSDB中,而后再将这个序列号写到磁盘。Each Block is composed by few files storing the chunks and the block index.

Service

Cortex 实际上是一个微服务的架构:服务体系有:

  • Distributor
  • Ingester
  • Querier
  • Query Frontend
  • Ruler
  • Altermanager
  • Config API

Distributor

这是咱们处理来自 Prometheus 数据的入口。直译过来就是数据的发起者。 distributor 收到 Prometheus 的数据后,会验证每一个样本的正确性并确保其在租户限制内,若是未覆盖特定租户的限制,则返回默认值。而后将有效样品数据分红几批,并并行发送至多个 ingesters
Distributor须要完成的验证包括:

  • The metric labels name are formally correct (指标标签名称形式正确)
  • The configured max number of labels per metric is respected (遵照每一个度量标准配置的最大标签数)
  • The configured max length of a label name and value is respected (注意标签名称和值的最大配置长度)
  • The timestamp is not older/newer than the configured min/max time range (时间戳不早于/晚于配置的最小/最大时间范围)

Distributor无状态的 , 能够根据须要进行放大缩小。

High Availability Tracker

Distributor 中的 HA 跟踪器 , distributor 将对来自 Prometheus 的冗余的数据样本进行重复数据的删除。至关因而说咱们拿到的 Prometheus 服务器的多个 HA 副本,将相同的数据写入 Cortex , 而后在 Distributor 里面作重复数据删除。

HA Tracker基于集群和副本标签消除传入样本的重复数据。群集标签惟一标识给定租户的冗余普罗米修斯服务器群集,而副本标签惟一标识普罗米修斯群集内的副本。若是收到的任何副本不是集群中的当前主副本,则认为传入的样本是重复的(并所以被丢弃)。

HA跟踪器须要一个键值(KV)存储来协调当前选择哪一个副本。分销商将只接受当前负责人的样品。默认状况下,不带标签(副本和群集)的样本将被接受,而且永远不会进行重复数据删除。

目前支持的这个 KV 存储有:

  • Consul
  • Etcd

Hashing

在 Distributor 使用一致的哈希,来决定由哪一个指定的 inester 来接收给定的序列。Cortex支持两种哈希策略:

  • Hash the metric name and tenant ID。默认的
  • Hash the metric name, labels and tenant ID。(-distributor.shard-by-all-labels=true)

hashing

Hash Ring

hash ring 是存储在 kv store 里面的,用于实现序列分片和复制的一致哈希。每个 Ingester 都会将自身的一个 token 注册到 这个 DHT (Distribute Hash Table)里面,这里也就是咱们的 Hash Ring.

目前 Hash Ring 支持的 KV 存储包括:

  • Consul
  • Etcd
  • Gossip memberlist(测试阶段)

Quorum Consistency

因为咱们全部的 Distributors 抖共享同一个 Hash Ring , 所以任何一个请求在发送道 Distributor 前均可以在前面设置一个无状态的负载均衡。

为保持查询结果的一致性,Cortex在读/写的时候使用了 Dyname StyleQuorum Consistency.这意味这 在发送一个 sample 到成功响应 Prometheus 请求以前,distributor 须要等待 一半加一个 的 Ingester 的积极响应。

Ingester

ingester 主要是将接收到的序列写入到 一个长期存储的后端 (long-term storage backend) , 并返回内存中的序列用于读取路径上的查询。

接收到的序列不会当即写入到存储里面,而是保存在内存中按期刷新到存储(默认状况下:Chunks 周期是12h , Block 是 2h ),所以 queriers 在执行 读物路径的查询的时候,须要同时从 ingesters 和 long-term storge 上抓取 sample (也就是说,我要查什么东西,要从这两个地方去查)

Inester 包含一个 lifecycler ,管理着一个 ingester 的生命周期,并将 ingester state 存储在 Hash Ring 里面。 Ingester 的状态有下:

  • PENDING:
  • JOINING:
  • ACTIVE: 当它被彻底初始化。它能够同时收到它拥有的令牌的写入和读取请求。
  • LEAVING:
  • UNHEALTHY: 当它未能检测到环的KV存储,在此状态下,分发服务器在为传入系列构建复制集时跳过 inester,而且 inester 不会接收写入或读取请求

PENDING说明

`
PENDING is an ingester’s state when it just started and is waiting for a hand-over from another ingester that is LEAVING. If no hand-over occurs within the configured timeout period (“auto-join timeout”, configurable via -ingester.join-after option), the ingester will join the ring with a new set of random tokens (ie. during a scale up). When hand-over process starts, state changes to JOINING.
`

JOINING说明

`
JOINING is an ingester’s state in two situations. First, ingester will switch to a
JOINING state from PENDING state after auto-join timeout. In this case, ingester
will generate tokens, store them into the ring, optionally observe the ring for
token conflicts and then move to ACTIVE state. Second, ingester will also switch
into a JOINING state as a result of another LEAVING ingester initiating a hand-over
process with PENDING (which then switches to JOINING state). JOINING ingester then
receives series and tokens from LEAVING ingester, and if everything goes well,
JOINING ingester switches to ACTIVE state. If hand-over process fails, JOINING
ingester will move back to PENDING state and either wait for another hand-over or
auto-join timeout.
`

LEAVING说明

`
LEAVING is an ingester’s state when it is shutting down. It cannot receive write requests anymore, while it could still receive read requests for series it has in memory. While in this state, the ingester may look for a PENDING ingester to start a hand-over process with, used to transfer the state from LEAVING ingester to the PENDING one, during a rolling update (PENDING ingester moves to JOINING state during hand-over process). If there is no new ingester to accept hand-over, ingester in LEAVING state will flush data to storage instead.
`

Ingesters 是半状态

Ingesters 故障或者数据丢失

若是说 ingester 崩溃了,全部的 还在内存中的等待刷新到 long-term storage 的数据都会丢失。有两个方式去解决:

复制

这个主要是从一个 ingester 复制到 另外一个 ingester . 若是出现单个的 ingester 挂了,数据是不会丢失的,但要是屡次的 ingester 的瘫痪,则 数据可能会丢失。
replication

预写日志(WAL)

这就是将咱们的数据临时先进行持久化,直到数据被刷新到 long-term storage 。

若是 ingester 失败了, 后续的进程将从新读取 WAL 并恢复到 内存

Ingesters write de-amplification

Ingester 收到的 sample 写入内存,以便用于 perform write de-amplification , 若是当即写入到 long-term storge ,系统的存储压力会比较大,并且很难扩展。
querier

Querier

查询器是支持使用 PromQL进行查询的,也就是说能够直接和 Grafana 进行对接。

querier

查询器是无状态的。可根据须要去进行向上或者向下的扩展。

Querier fronted

这里主要是针对 API 的查询方式

Caching

查询前端会对上一次的查询结果作一次缓存,下一次若是重现重复的查询操做,直接从缓存拿数据,不然到下一级去处理。

Rule

这是 执行 PromQL 查询记录 的 rules(规则) 和 alerts(警报)

Rule 会将每一个租户的 rules / alters 存储在一个数据库 PostgreSQL .

Cortex 的扩展

querier

相关文章
相关标签/搜索