> Discover all available pages from the documentation index: https://mastra.zisheng.pro/llms.txt # ClickHouse 存储 [ClickHouse](https://clickhouse.com/) 是专为分析工作负载设计的列式数据库。`@mastra/clickhouse` 包为多个 Mastra storage domain 提供存储适配器,是生产环境 observability 的推荐后端。 ClickHouse 最常作为[组合存储](https://mastra.zisheng.pro/reference/storage/composite)配置中的专用 observability 后端,其他 domain 则由另一数据库提供服务。 ## 何时使用 ClickHouse 用于生产环境的 traces、logs、metrics、scores 和 feedback 的 observability。 本地开发时,请使用组合 [LibSQL](https://mastra.zisheng.pro/reference/storage/libsql)(用于 memory 和 workflows)与 `@mastra/duckdb`(用于 observability)的 composite store。二者单独使用都不能覆盖开发环境:LibSQL 未实现 observability domain,而 DuckDB 未实现其他 domain。示例请参阅 [observability 概览](https://mastra.zisheng.pro/docs/observability/overview)。 ## 安装 **npm**: ```bash npm install @mastra/clickhouse@latest ``` **pnpm**: ```bash pnpm add @mastra/clickhouse@latest ``` **Yarn**: ```bash yarn add @mastra/clickhouse@latest ``` **Bun**: ```bash bun add @mastra/clickhouse@latest ``` 你还需要运行中的 ClickHouse server。有关托管和自托管选项,请参阅[托管选项](#hosting-options)。 ## 使用方法 ### 使用 vNext 的 observability(推荐) `ObservabilityStorageClickhouseVNext` 是当前的 observability domain 实现。它使用由 `ReplacingMergeTree` 支持的仅插入 schema,并针对 traces、logs、metrics、scores 和 feedback 产生的数据量进行了优化。 将其与另一存储适配器组合,以避免 observability 写入与应用程序数据争抢资源: ```typescript import { Mastra } from '@mastra/core' import { MastraCompositeStore } from '@mastra/core/storage' import { PostgresStore } from '@mastra/pg' import { ObservabilityStorageClickhouseVNext } from '@mastra/clickhouse' import { Observability, MastraStorageExporter } from '@mastra/observability' const observabilityStore = new ObservabilityStorageClickhouseVNext({ url: process.env.CLICKHOUSE_URL!, username: process.env.CLICKHOUSE_USERNAME!, password: process.env.CLICKHOUSE_PASSWORD!, }) export const mastra = new Mastra({ storage: new MastraCompositeStore({ id: 'composite-storage', default: new PostgresStore({ id: 'pg', connectionString: process.env.DATABASE_URL!, }), domains: { observability: observabilityStore, }, }), observability: new Observability({ configs: { default: { serviceName: 'mastra', exporters: [new MastraStorageExporter()], }, }, }), }) ``` 当 ClickHouse 是 observability 后端时,`MastraStorageExporter` 会自动选择 `insert-only` 策略,以获得最高写入吞吐量。详情请参阅 [tracing 策略](https://mastra.zisheng.pro/docs/observability/integrations/exporters/mastra-storage)。 ### 使用 legacy domain 的 observability `ObservabilityStorageClickhouse` 是原始的 observability adapter,尚未迁移到 vNext schema 的项目仍受支持。其配置形式与 vNext class 相同。 ```typescript import { ObservabilityStorageClickhouse } from '@mastra/clickhouse' const observabilityStore = new ObservabilityStorageClickhouse({ url: process.env.CLICKHOUSE_URL!, username: process.env.CLICKHOUSE_USERNAME!, password: process.env.CLICKHOUSE_PASSWORD!, }) ``` 新项目应改用 `ObservabilityStorageClickhouseVNext`。 ### 从 legacy 迁移到 vNext 要将历史 spans 从 legacy `mastra_ai_spans` 表迁移到 vNext schema,请运行: **npm**: ```bash npx mastra migrate ``` **pnpm**: ```bash pnpm dlx mastra migrate ``` **Yarn**: ```bash yarn dlx mastra migrate ``` **Bun**: ```bash bun x mastra migrate ``` 迁移会按天大小的批次将 span 数据从 `mastra_ai_spans` 复制到 `mastra_span_events`。它会处理列映射并对 legacy rows 去重。原始表将保留作为备份。迁移后,traces 会通过 vNext adapter 显示在 Studio 中。 > **备注:** legacy 表不会被删除。验证迁移结果后,请手动删除它。 ### 将 ClickHouse 用于每个 domain `ClickhouseStoreVNext` 使用 ClickHouse 支持 `memory`、`workflows` 和 `observability` domains,并自动使用 vNext observability adapter。当你希望 ClickHouse 支持整个应用程序、且不想手动配置 composite store 时,请使用它。 ```typescript import { Mastra } from '@mastra/core' import { ClickhouseStoreVNext } from '@mastra/clickhouse' export const mastra = new Mastra({ storage: new ClickhouseStoreVNext({ id: 'clickhouse-storage', url: process.env.CLICKHOUSE_URL!, username: process.env.CLICKHOUSE_USERNAME!, password: process.env.CLICKHOUSE_PASSWORD!, }), }) ``` `ClickhouseStoreVNext` 接受与 `ClickhouseStore` 相同的配置,并在每个 domain 中复用同一个 ClickHouse client。 #### 手动组合 `ClickhouseStore` 是长期以来使用 legacy observability adapter 支持每个 domain 的 class。新项目应优先使用 `ClickhouseStoreVNext`。如果需要自定义 composite(例如,使用不同后端覆盖某个 domain),请手动构建: ```typescript import { Mastra } from '@mastra/core' import { MastraCompositeStore } from '@mastra/core/storage' import { ClickhouseStore, ObservabilityStorageClickhouseVNext } from '@mastra/clickhouse' const credentials = { url: process.env.CLICKHOUSE_URL!, username: process.env.CLICKHOUSE_USERNAME!, password: process.env.CLICKHOUSE_PASSWORD!, } export const mastra = new Mastra({ storage: new MastraCompositeStore({ id: 'composite-storage', default: new ClickhouseStore({ id: 'clickhouse-storage', ...credentials }), domains: { observability: new ObservabilityStorageClickhouseVNext(credentials), }, }), }) ``` ### 使用自己的 ClickHouse client 当你需要请求超时、压缩或 interceptors 等自定义连接设置时,请传入预先配置的 client: ```typescript import { createClient } from '@clickhouse/client' import { ClickhouseStore } from '@mastra/clickhouse' const client = createClient({ url: process.env.CLICKHOUSE_URL!, username: process.env.CLICKHOUSE_USERNAME!, password: process.env.CLICKHOUSE_PASSWORD!, request_timeout: 60_000, compression: { request: true, response: true }, }) const storage = new ClickhouseStore({ id: 'clickhouse-storage', client }) ``` `ObservabilityStorageClickhouse` 和 `ObservabilityStorageClickhouseVNext` 也接受相同形式的 `client`。 ## 配置 ### `ClickhouseStore` 选项 **id** (`string`): 此存储实例的唯一标识符。 **url** (`string`): ClickHouse server URL(例如,https\://your-instance.clickhouse.cloud:8443 或 http\://localhost:8123)。未传入预先配置的 client 时必填。 **username** (`string`): ClickHouse username。未传入预先配置的 client 时必填。 **password** (`string`): ClickHouse password。未传入预先配置的 client 时必填。本地实例的默认 user 可以使用空字符串。 **client** (`ClickHouseClient`): 来自 @clickhouse/client 的预先配置的 ClickHouse client。需要自定义请求设置时使用它。与上述凭据字段互斥。 **ttl** (`object`): 在创建表时应用的每表 TTL 配置。接受从 NANOSECOND 到 YEAR 的 interval 单位的 row-level 和 column-level TTL。 **replication** (`{ cluster?: string; zookeeperPath?: string; replicaName?: string }`): 适用于多副本 ClickHouse cluster 的可选 replicated table 配置。设置后,Mastra 会创建 replicated MergeTree tables。设置 cluster 后,Mastra 还会向由 Mastra 管理的 data definition language (DDL) 添加 ON CLUSTER。 **disableInit** (`boolean`): 为 true 时,store 在首次使用时不会创建表或运行 migrations。请从 deployment scripts 中显式调用 storage.init()。 (Default: `false`) `ClickhouseStore` 还接受 `ClickHouseClientConfigOptions` 中的所有选项(例如 `database`、`request_timeout`、`compression`、`keep_alive` 和 `max_open_connections`)。 ### Replicated clusters 当 Mastra 通过 load balancer 向多副本 ClickHouse cluster 写入数据时,请使用 `replication`。 ```typescript const storage = new ClickhouseStoreVNext({ id: 'clickhouse-storage', url: process.env.CLICKHOUSE_URL!, username: process.env.CLICKHOUSE_USERNAME!, password: process.env.CLICKHOUSE_PASSWORD!, replication: { cluster: 'company_cluster', }, }) ``` 设置 `replication` 后,Mastra 会将其 `MergeTree` 和 `ReplacingMergeTree` table engines 改写为 `ReplicatedMergeTree` 和 `ReplicatedReplacingMergeTree`。默认 engine arguments 为: - `zookeeperPath`: `'/clickhouse/tables/{shard}/{database}/{table}'` - `replicaName`: `'{replica}'` 默认值符合最常见的 self-managed convention。如果 cluster 中的现有 tables 使用不同的布局(例如不含 `{database}` 部分的 `/clickhouse/tables/{shard}/{table}`),请显式设置 `zookeeperPath` 以匹配该布局。Mastra 不会从 Keeper 读取 cluster 的 convention,因此不匹配的默认值会将 Mastra 的 metadata 写入与 cluster 其他部分分离的 branch。 ```typescript new ClickhouseStoreVNext({ url: process.env.CLICKHOUSE_URL!, username: process.env.CLICKHOUSE_USERNAME!, password: process.env.CLICKHOUSE_PASSWORD!, replication: { cluster: 'company_cluster', zookeeperPath: '/clickhouse/tables/{shard}/{table}', }, }) ``` 设置 `cluster` 可将 `ON CLUSTER` 添加到由 Mastra 管理的 DDL,例如创建表、创建 materialized view、column migrations、TTL changes 和删除表。 设置 `cluster` 后,`optimizeTable()` 和 `materializeTtl()` 等手动维护操作会在每个 replica 上运行。这些操作在大型 cluster 上可能成本很高。请优先在非高峰时段运行它们,并让常规 merges 在 background merge queue 上进行,而不是在每次重启时触发。 如果现有 Mastra tables 使用本地 `MergeTree` 或 `ReplacingMergeTree` engines,在启用 `replication` 时初始化会失败。由于 copy-and-swap 在 replicas 间并不安全,Mastra 拒绝静默转换 local tables。要迁移,请先将受影响的 tables 重新创建为 `Replicated*`,再启用 replication。为安全迁移,请重命名 local table,运行 `CREATE TABLE ... ENGINE = ReplicatedMergeTree(...) ON CLUSTER ...`,运行 `INSERT INTO ... SELECT * FROM `,然后删除 ``。 不要在 ClickHouse Cloud 上设置 `replication`。Cloud 会在 server-side 将 `MergeTree` 改写为 `SharedMergeTree`,而显式的 `ReplicatedMergeTree` engines 会生成错误的 DDL。`replication` 仅适用于 self-managed 多副本 clusters。 ### Observability domain 选项 `ObservabilityStorageClickhouse` 和 `ObservabilityStorageClickhouseVNext` 接受与 `ClickhouseStore` 相同的连接选项(`url`、`username`、`password` 或预先配置的 `client`)。 ## 托管选项 只要可以通过 HTTP 访问,ClickHouse 就能运行。常见选择包括: - **[ClickHouse Cloud](https://clickhouse.com/cloud)**:提供免费试用层级的托管服务。提供可直接用于 `url`、`username` 和 `password` 的连接详情。 - **Self-hosted**:运行官方 [`clickhouse/clickhouse-server`](https://hub.docker.com/r/clickhouse/clickhouse-server) container,或通过[官方 packages](https://clickhouse.com/docs/en/install) 安装。适用于 VPS、专用硬件或 Kubernetes。 本地开发时: ```bash docker run -d --name mastra-clickhouse \ -p 8123:8123 -p 9000:9000 \ -e CLICKHOUSE_USER=default \ -e CLICKHOUSE_PASSWORD=password \ clickhouse/clickhouse-server ``` ```typescript new ObservabilityStorageClickhouseVNext({ url: 'http://localhost:8123', username: 'default', password: 'password', }) ``` ## 部署到 Railway 及类似平台 [Railway](https://railway.com)、[Fly.io](https://fly.io)、[Render](https://render.com) 和 Heroku 等平台会在 ephemeral filesystems 上运行 application containers。DuckDB 等嵌入式 observability backends 需要可写的 persistent local file,因此它们要么会在重启时丢失数据,要么根本无法部署到这些平台。 请改用 ClickHouse。由于 ClickHouse 可通过 HTTP 访问,相同的连接可从任意 host 使用: ```typescript import { Mastra } from '@mastra/core' import { MastraCompositeStore } from '@mastra/core/storage' import { PostgresStore } from '@mastra/pg' import { ObservabilityStorageClickhouseVNext } from '@mastra/clickhouse' import { Observability, MastraStorageExporter } from '@mastra/observability' export const mastra = new Mastra({ storage: new MastraCompositeStore({ id: 'composite-storage', default: new PostgresStore({ id: 'pg', connectionString: process.env.DATABASE_URL!, }), domains: { observability: new ObservabilityStorageClickhouseVNext({ url: process.env.CLICKHOUSE_URL!, username: process.env.CLICKHOUSE_USERNAME!, password: process.env.CLICKHOUSE_PASSWORD!, }), }, }), observability: new Observability({ configs: { default: { serviceName: 'mastra', exporters: [new MastraStorageExporter()], }, }, }), }) ``` 可采用以下任一方式配置 database: - **Managed**:使用 ClickHouse Cloud。在 hosting platform 中将 `CLICKHOUSE_URL`、`CLICKHOUSE_USERNAME` 和 `CLICKHOUSE_PASSWORD` 设置为 environment variables。 - **Self-hosted on Railway**:从官方 Docker image 向 Railway project 添加 ClickHouse service,然后通过 Railway 的 private networking 在 application service 中引用它。 同一方法适用于其他使用 ephemeral filesystems 的 hosts。对于也应存储在 host 外的 application data,请将此配置与用于 `default` storage 的托管 PostgreSQL 或 LibSQL/Turso instance 配合使用。 > **注意:** 不要将 DuckDB 等嵌入式 backend 指向 ephemeral container filesystem 内的 path。container 重启时,写入该处的数据会丢失;在某些平台上,该 path 是只读的。 ## 初始化 传入 `Mastra` class 后,`ClickhouseStore` 会自动调用 `init()` 以创建 schema 并运行所有待处理的 migrations。通过 `MastraCompositeStore` 使用 `ObservabilityStorageClickhouseVNext` 时也是如此。 如果你在 `Mastra` 外管理 storage,请显式调用 `init()`: ```typescript import { ObservabilityStorageClickhouseVNext } from '@mastra/clickhouse' const observability = new ObservabilityStorageClickhouseVNext({ url: process.env.CLICKHOUSE_URL!, username: process.env.CLICKHOUSE_USERNAME!, password: process.env.CLICKHOUSE_PASSWORD!, }) await observability.init() ``` 在 CI/CD pipelines 中,请在 `ClickhouseStore` 上设置 `disableInit: true`,并从使用 elevated credentials 的 deployment step 运行 `init()`。这样,runtime application credentials 就可以限制为 read 和 insert。 ## Observability ClickHouse 是生产环境 observability 的推荐 backend: - **Insert-only strategy**:`MastraStorageExporter` 批量写入已完成的 spans,且不进行逐 span 更新,这是可用的最高吞吐量策略。 - **Columnar compression**:与 row-oriented databases 中的相同数据相比,span attributes 和 log payloads 的压缩效果更佳。 完整的策略矩阵和生产环境指南请参阅 [`MastraStorageExporter` 参考](https://mastra.zisheng.pro/docs/observability/integrations/exporters/mastra-storage)。 ## 相关内容 - [Storage 概览](https://mastra.zisheng.pro/reference/storage/overview) - [组合存储](https://mastra.zisheng.pro/reference/storage/composite) - [`MastraStorageExporter`](https://mastra.zisheng.pro/docs/observability/integrations/exporters/mastra-storage) - [Observability 概览](https://mastra.zisheng.pro/docs/observability/overview)