> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-parallel-read-in-order-multi-part.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> ClickHouse 中的 Prometheus HTTP API 支持：基于 TimeSeries 表的远程写入、远程读取和 PromQL 查询。

# Prometheus HTTP API 和 PromQL

export const PrivatePreviewBadge = () => {
  return <div className="privatePreviewBadge">
            <div className="privatePreviewIcon">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M5.33301 6.66667V4.66667V4.66667C5.33301 3.194 6.52701 2 7.99967 2V2C9.47234 2 10.6663 3.194 10.6663 4.66667V4.66667V6.66667" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path d="M8.00033 9.33337V11.3334" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path fillRule="evenodd" clipRule="evenodd" d="M11.333 14H4.66634C3.92967 14 3.33301 13.4033 3.33301 12.6666V7.99996C3.33301 7.26329 3.92967 6.66663 4.66634 6.66663H11.333C12.0697 6.66663 12.6663 7.26329 12.6663 7.99996V12.6666C12.6663 13.4033 12.0697 14 11.333 14Z" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
        </div>
            {'私有预览'}
        </div>;
};

<PrivatePreviewBadge />

ClickHouse 基于 [`TimeSeries`](/zh/reference/engines/table-engines/integrations/time-series) 表实现 Prometheus HTTP API。一个处理程序可处理 远程写入、远程读取、即时 PromQL 查询和范围 PromQL 查询。

若要暴露 ClickHouse 自身的指标以供 Prometheus 服务器 抓取，请参阅 [Prometheus 指标端点](/zh/concepts/features/interfaces/prometheus-metrics)。

<h2 id="prerequisites">
  前置条件
</h2>

ClickHouse Cloud 与自管理 ClickHouse 的设置步骤有所不同。请参照与你的部署方式相对应的章节进行操作。

<h3 id="prerequisites-cloud">
  ClickHouse Cloud
</h3>

<Note>
  ClickHouse Cloud 中的 PromQL 支持目前处于私有预览阶段。参与私有预览的服务已配置好 `enable_time_series_table` 设置以及 Prometheus API 端点。其他 ClickHouse Cloud 服务不具备该配置，你也无法自行在这类服务上启用该功能。后续章节中的 `SET enable_time_series_table` 语句和 `http_handlers` 配置仅适用于自管理部署。
</Note>

如果你的服务参与了私有预览，请直接跳至[创建 TimeSeries 表](#create-a-timeseries-table)。该服务会提供[端点表](#configure-prometheus-api)中列出的端点路径。

<h3 id="enable-the-timeseries-setting">
  自管理：启用 TimeSeries 设置
</h3>

为创建和访问该表的用户启用 `enable_time_series_table` 设置：

```sql theme={null}
SET enable_time_series_table = 1;
```

对于 HTTP API 请求，请在 API 用户的 profile 中启用 `enable_time_series_table`。

<h3 id="configure-prometheus-api">
  自管理：配置 Prometheus API 端点
</h3>

在主 ClickHouse HTTP 端口上配置一个按前缀路由的处理程序：

```xml theme={null}
<http_handlers>
    <defaults/>
    <rule>
        <url_prefix>/prometheus/api/v1</url_prefix>
        <handler>
            <type>prometheus_api_v1</type>
        </handler>
    </rule>
</http_handlers>
```

`<defaults/>` 会保留 `/ping` 等端点和 SQL 请求的内置处理程序。上述前缀通过一个处理程序公开这些端点：

| 端点 | 用途 |
| - | - |
| `/prometheus/api/v1/write` | Prometheus 远程写入 |
| `/prometheus/api/v1/read` | Prometheus 远程读取 |
| `/prometheus/api/v1/query` | 即时 PromQL 查询 |
| `/prometheus/api/v1/query_range` | 范围 PromQL 查询 |
| `/prometheus/api/v1/format_query` | PromQL 表达式格式化 |
| `/prometheus/api/v1/series` | 序列元数据 |
| `/prometheus/api/v1/metadata` | 指标家族元数据 |

该示例未在处理程序中指定 `database` 和 `table`。每个请求都必须提供 `table` 查询参数 (`/format_query` 除外，它只解析给定的 PromQL 表达式，不需要表) 。还可以提供 `database`、使用如 `prometheus.metrics` 这样的限定表名，或者省略数据库以使用 `default`。这样，一个处理程序即可为多个 `TimeSeries` 表提供服务。

若要让所有请求使用同一个固定表，请在处理程序中进行配置：

```xml theme={null}
<handler>
    <type>prometheus_api_v1</type>
    <database>prometheus</database>
    <table>metrics</table>
</handler>
```

在处理程序中配置的表不能被请求参数覆盖。

路由和处理程序设置：

| 名称 | 默认值 | 描述 |
| - | - | - |
| `url_prefix` | 无 | 用于匹配所有以配置前缀开头的请求路径的规则过滤器。 |
| `table` | 无 | `TimeSeries` 表的名称。未指定时，请求必须提供 `table` 查询参数。配置的名称可以包含数据库名称。 |
| `database` | 无 | 包含该表的数据库。请求可通过查询参数提供该值。未指定时，ClickHouse 会使用完全限定的 `table` 值中的数据库，或回退到 `default`。 |

<h3 id="create-a-timeseries-table">
  创建 TimeSeries 表
</h3>

创建数据库和 `TimeSeries` 表：

```sql theme={null}
CREATE DATABASE prometheus;
CREATE TABLE prometheus.metrics ENGINE = TimeSeries;
```

<h2 id="remote-write">
  通过 远程写入 摄取指标
</h2>

ClickHouse 支持 [Prometheus 远程写入 协议](https://prometheus.io/docs/specs/remote_write_spec/)。配置 Prometheus 以向该处理程序写入数据：

```yaml theme={null}
remote_write:
  - url: https://clickhouse.example.com:8443/prometheus/api/v1/write?database=prometheus&table=metrics
    basic_auth:
      username: default
      password: <password>
```

Prometheus 会将样本写入 `prometheus.metrics` 表。

要将多个并发远程写入请求中的数据合并为更少的 parts，请在 URL 中添加 `async_insert` 设置 (或在 user profile 中启用该设置) ，以启用[异步插入](/zh/reference/settings/session-settings/async-insert#async_insert)：

```yaml theme={null}
remote_write:
  - url: https://clickhouse.example.com:8443/prometheus/api/v1/write?database=prometheus&table=metrics&async_insert=1
```

ClickHouse 仅在数据已刷新到 `TimeSeries` 表的所有内部表后，才会确认异步远程写入请求，不受 [`wait_for_async_insert`](/zh/reference/settings/session-settings/wait-for#wait_for_async_insert) 设置影响：远程写入协议将已确认的写入视为持久化写入。如果刷新失败，请求会返回错误，Prometheus 将重试。

<h2 id="promql-query-support">
  使用 PromQL 查询
</h2>

使用即时查询端点，在某一时间点评估 PromQL 表达式：

```bash theme={null}
curl --user default:<password> --get \
  "https://clickhouse.example.com:8443/prometheus/api/v1/query" \
  --data-urlencode "query=rate(http_requests_total[5m])" \
  --data-urlencode "database=prometheus" \
  --data-urlencode "table=metrics"
```

使用范围查询端点计算指定时间范围内的表达式：

```bash theme={null}
curl --user default:<password> --get \
  "https://clickhouse.example.com:8443/prometheus/api/v1/query_range" \
  --data-urlencode "query=rate(http_requests_total[5m])" \
  --data-urlencode "start=2026-08-15T12:00:00Z" \
  --data-urlencode "end=2026-08-15T13:00:00Z" \
  --data-urlencode "step=60s" \
  --data-urlencode "database=prometheus" \
  --data-urlencode "table=metrics"
```

查询端点也接受以表单请求正文形式传递的参数。若不使用 `--get`，curl 会通过 `POST` 以 `application/x-www-form-urlencoded` 发送这些参数：

```bash theme={null}
curl --user default:<password> \
  "https://clickhouse.example.com:8443/prometheus/api/v1/query_range" \
  --data-urlencode "query=rate(http_requests_total[5m])" \
  --data-urlencode "start=2026-08-15T12:00:00Z" \
  --data-urlencode "end=2026-08-15T13:00:00Z" \
  --data-urlencode "step=60s" \
  --data-urlencode "database=prometheus" \
  --data-urlencode "table=metrics"
```

使用格式化查询端点解析并格式化 PromQL 表达式，而不对其求值：

```bash theme={null}
curl --user default:<password> --get \
  "https://clickhouse.example.com:8443/prometheus/api/v1/format_query" \
  --data-urlencode "query=sum by(job)(http_requests_total{code=\"200\"})/2"
```

该表达式会从解析后的查询中序列化返回，其中空白已归一化、注释已移除、冗余括号已去除，时长也转换为秒数：`sum by (job) (http_requests_total{code="200"}) / 2`。该端点不会对表达式求值，因此不需要 `database` 和 `table` 参数。

有关 HTTP API、`promql` 方言及表函数支持的函数和聚合运算符列表，请参阅[支持的 PromQL 功能](/zh/reference/functions/table-functions/prometheusQueryRange#supported-promql-features)。

<h3 id="grafana">
  Grafana
</h3>

配置 Prometheus 数据源时，基础 URL 应以 `/api/v1` 之前的部分结尾：

```yaml theme={null}
apiVersion: 1
datasources:
  - name: ClickHouse Prometheus
    type: prometheus
    access: proxy
    url: https://clickhouse.example.com:8443/prometheus
    basicAuth: true
    basicAuthUser: default
    jsonData:
      httpMethod: POST
      customQueryParameters: database=prometheus&table=metrics
    secureJsonData:
      basicAuthPassword: <password>
```

Grafana 会将 `/api/v1/query` 或 `/api/v1/query_range` 追加到此基础 URL，并在每个请求中添加 `customQueryParameters`。

在 `httpMethod: POST` 下，Grafana 会将查询参数放在请求正文中发送。ClickHouse 会同时读取请求正文和 URL 查询字符串，因此 `customQueryParameters` 仍然生效。对于较长的 PromQL 表达式，请使用 `POST`，因为 URL 存在长度限制。

<Note>
  目前仅实现了查询端点 `/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 数据源用于浏览标记、模板变量和查询构建器自动补全的功能。
</Note>

<h3 id="sql-entry-points">
  SQL 入口
</h3>

ClickHouse 的 HTTP API、`promql` 方言以及 [`prometheusQuery`](/zh/reference/functions/table-functions/prometheusQuery) 和 [`prometheusQueryRange`](/zh/reference/functions/table-functions/prometheusQueryRange) 表函数均使用同一个 PromQL 转换器。

使用 `clickhouse-client` 直接执行 PromQL：

```bash theme={null}
clickhouse-client \
  --dialect promql \
  --promql_database prometheus \
  --promql_table metrics \
  --query 'rate(http_requests_total[5m])'
```

使用表函数在 SQL 查询中嵌入 PromQL：

```sql theme={null}
SELECT *
FROM prometheusQuery(
    prometheus.metrics,
    'rate(http_requests_total[5m])',
    now()
);
```

<h2 id="metadata">
  查询指标元数据
</h2>

`/prometheus/api/v1/metadata` 端点返回存储在 `TimeSeries` 表的 `Metrics` 目标表中的指标元数据，包括每个指标族的类型、帮助文本和单位。它支持 URL 查询字符串中的以下 Prometheus 参数：

| 参数 | 描述 |
| - | - |
| `metric` | 仅返回此指标族的元数据。 |
| `limit` | 限制返回的指标族数量。负值表示不限制；零表示不返回任何指标族。 |
| `limit_per_metric` | 限制每个指标族返回的元数据对象数量。零和负值表示不限制。 |

默认的 `Metrics` 目标表是按指标族名称排序的 `ReplacingMergeTree`：它会保留每个指标族最近写入的元数据条目。只有在目标表仍保留这些条目时，才会返回每个指标族的多个条目——例如在其 parts 合并之前，或该表使用会保留这些条目的引擎时。

```bash theme={null}
curl --user default:<password> --get \
  "https://clickhouse.example.com:8443/prometheus/api/v1/metadata" \
  --data-urlencode "metric=http_requests_total" \
  --data-urlencode "database=prometheus" \
  --data-urlencode "table=metrics"
```

<h2 id="remote-read">
  通过远程读取读取指标
</h2>

ClickHouse 在 `/prometheus/api/v1/read` 提供对 [Prometheus 远程读取协议](https://prometheus.io/docs/prometheus/latest/querying/remote_read_api/)的支持。

配置 Prometheus 服务器从同一个 `TimeSeries` 表中读取数据：

```yaml theme={null}
remote_read:
  - url: https://clickhouse.example.com:8443/prometheus/api/v1/read?database=prometheus&table=metrics
    basic_auth:
      username: default
      password: <password>
```
