TimeSeries 表实现 Prometheus HTTP API。一个处理程序可处理 远程写入、远程读取、即时 PromQL 查询和范围 PromQL 查询。
若要暴露 ClickHouse 自身的指标以供 Prometheus 服务器 抓取,请参阅 Prometheus 指标端点。
前置条件
ClickHouse Cloud 与自管理 ClickHouse 的设置步骤有所不同。请参照与你的部署方式相对应的章节进行操作。ClickHouse Cloud
ClickHouse Cloud 中的 PromQL 支持目前处于私有预览阶段。参与私有预览的服务已配置好
enable_time_series_table 设置以及 Prometheus API 端点。其他 ClickHouse Cloud 服务不具备该配置,你也无法自行在这类服务上启用该功能。后续章节中的 SET enable_time_series_table 语句和 http_handlers 配置仅适用于自管理部署。自管理:启用 TimeSeries 设置
为创建和访问该表的用户启用enable_time_series_table 设置:
enable_time_series_table。
自管理:配置 Prometheus API 端点
在主 ClickHouse HTTP 端口上配置一个按前缀路由的处理程序:<defaults/> 会保留 /ping 等端点和 SQL 请求的内置处理程序。上述前缀通过一个处理程序公开这些端点:
该示例未在处理程序中指定
database 和 table。每个请求都必须提供 table 查询参数 (/format_query 除外,它只解析给定的 PromQL 表达式,不需要表) 。还可以提供 database、使用如 prometheus.metrics 这样的限定表名,或者省略数据库以使用 default。这样,一个处理程序即可为多个 TimeSeries 表提供服务。
若要让所有请求使用同一个固定表,请在处理程序中进行配置:
创建 TimeSeries 表
创建数据库和TimeSeries 表:
通过 远程写入 摄取指标
ClickHouse 支持 Prometheus 远程写入 协议。配置 Prometheus 以向该处理程序写入数据:prometheus.metrics 表。
为了将多个并发远程写入请求中的数据合并为更少的 parts,ClickHouse 会使用异步插入。该功能默认启用,可通过 URL (或 user profile) 中的 async_insert 设置开启或关闭。
ClickHouse 仅在数据已刷写到 TimeSeries 表的所有内部表后,才会确认异步远程写入请求,不受 wait_for_async_insert 设置影响:远程写入协议将已确认的写入视为持久化写入。如果刷写失败,请求会返回错误,Prometheus 将重试。
由于每个请求都要等待其刷写完成,异步插入会限制单个发送方的写入速度。Prometheus 对每个远程写入分片一次只发送一个请求。当多个分片同时发送时,自适应刷写超时会逐步增大至 async_insert_busy_timeout_max_ms,除非待处理请求的数据量先达到 async_insert_max_data_size。请求会一直等到其所在批次被刷写,而刷写最晚会在该批次开始后经过上述时长时发生。因此在持续负载下,每个分片的写入速率约为 samples per request / async_insert_busy_timeout_max_ms,其中 Prometheus 默认每个请求最多发送 2,000 个样本。要提高该速率,可以:
- 在
remote_write的queue_config中调高max_shards(默认为 50) 或max_samples_per_send。Prometheus 在写入滞后时会自动增加分片,最多增至max_shards。 - 在 URL 或 user profile 中调低
async_insert_busy_timeout_max_ms,例如&async_insert_busy_timeout_max_ms=50。这样刷写会更加频繁,而每次刷写都会在内部表中创建新的 parts。 - 通过
async_insert=0禁用异步插入。这样每个请求都会在内部表中创建各自的 parts。
使用 PromQL 查询
使用即时查询端点,在某一时间点评估 PromQL 表达式:--get,curl 会通过 POST 以 application/x-www-form-urlencoded 发送这些参数:
sum by (job) (http_requests_total{code="200"}) / 2。时长会保留单位,而不会转换为秒数,因此 rate(x[5m]) 返回为 rate(x[5m]);如果时长无法用单一单位的整数值表示,则会组合使用所需的单位,因此 rate(x[90s]) 返回为 rate(x[1m30s])。该端点不会对表达式求值,因此不需要 database 和 table 参数。
有关 HTTP API、promql 方言及表函数支持的函数和聚合运算符列表,请参阅支持的 PromQL 功能。
Grafana
配置 Prometheus 数据源时,基础 URL 应以/api/v1 之前的部分结尾:
/api/v1/query 或 /api/v1/query_range 追加到此基础 URL,并在每个请求中添加 customQueryParameters。
在 httpMethod: POST 下,Grafana 会将查询参数放在请求正文中发送。ClickHouse 会同时读取请求正文和 URL 查询字符串,因此 customQueryParameters 仍然生效。对于较长的 PromQL 表达式,请使用 POST,因为 URL 存在长度限制。
目前仅实现了查询端点
/api/v1/query、/api/v1/query_range 和 /api/v1/format_query 以及元数据端点 /api/v1/series、/api/v1/labels、/api/v1/label/<name>/values 和 /api/v1/metadata。/api/v1/series 至少需要一个 match[] 序列选择器,支持可选的 start、end 和 limit 参数,并返回每个选择器匹配的序列的并集。/api/v1/labels 接受相同的参数,其中 match[] 为可选项,并返回匹配的序列的已排序标记名称 (未提供选择器时则返回所有序列的标记名称) 。/api/v1/label/<name>/values 接受与 /api/v1/labels 相同的参数,并返回某个标记的已排序值,其中 <name> 可选地使用 Prometheus 的 U__... 转义方式来表示包含 [a-zA-Z0-9_] 之外字符的标记名称。这些端点涵盖了 Grafana Prometheus 数据源用于浏览标记、模板变量和查询构建器自动补全的功能。SQL 入口
ClickHouse 的 HTTP API、promql 方言以及 prometheusQuery 和 prometheusQueryRange 表函数均使用同一个 PromQL 转换器。
使用 clickhouse-client 直接执行 PromQL:
查询指标元数据
/prometheus/api/v1/metadata 端点返回存储在 TimeSeries 表的 Metrics 目标表中的指标元数据,包括每个指标族的类型、帮助文本和单位。它支持 URL 查询字符串中的以下 Prometheus 参数:
默认的
Metrics 目标表是按指标族名称排序的 ReplacingMergeTree:它会保留每个指标族最近写入的元数据条目。只有在目标表仍保留这些条目时,才会返回每个指标族的多个条目——例如在其 parts 合并之前,或该表使用会保留这些条目的引擎时。
通过远程读取读取指标
ClickHouse 在/prometheus/api/v1/read 提供对 Prometheus 远程读取协议的支持。
配置 Prometheus 服务器从同一个 TimeSeries 表中读取数据:
记录规则
ClickHouse 不会评估 Prometheus 规则文件。可刷新materialized view 可以起到记录规则的作用:它按调度计划计算 PromQL 表达式,并将结果追加到TimeSeries 表中。以下视图每分钟将 sum by (job) (rate(http_requests_total[5m])) 记录为 job:http_requests:rate5m:
mapUpdate 设置指标名称,并为结果中的每个数据系列追加一个样本。还可以在同一个 Map 中添加额外的标记,例如 map('__name__', 'job:http_requests:rate5m', 'team', 'web')。记录下来的数据系列可以像其他指标一样查询:
system.view_refreshes 中查看。
视图与 Prometheus 记录规则存在以下差异:
- 求值时间为刷新运行时的
now()。除按调度计划刷新外,视图还会在以下情况下刷新:创建后立即刷新 (除非创建时指定了EMPTY) ;若刷新并非协调式,则在服务器重启后刷新 (位于 Replicated 或 Shared 数据库之外的视图,或设置了all_replicas = 1的视图,不会记录其上次刷新) ;以及错过某次计划刷新后,通过SYSTEM START VIEW恢复时刷新。请参照示例将now()向下取整到时间间隔,以免这些刷新在两次计划刷新之间插入额外的样本。即便如此,额外的刷新仍可能在同一个取整后的时间戳上写入第二个样本。对于五分钟的规则,请使用toStartOfInterval(now(), INTERVAL 5 MINUTE)。 - 错过的求值不会补算。服务器宕机或视图停止后,视图只会对当前时间间隔求值,之前的时间间隔将保持为空。若某次刷新耗时超过时间间隔,也会出现同样的情况。
- 从结果中消失的数据系列不会被打上陈旧标记,因此在回溯周期 (默认 5 分钟) 内,查询仍会返回其最后记录的值。
- 没有规则文件:每条规则都是一个独立的视图,且不会出现在
/api/v1/rules的列表中。