> Discover all available pages from the documentation index: https://mastra.zisheng.pro/zh-TW/llms.txt # ClickHouse 儲存空間 [ClickHouse](https://clickhouse.com/) 是專為分析工作負載設計的欄式資料庫。`@mastra/clickhouse` 套件為多個 Mastra 儲存 domain 提供儲存 adapter,也是正式環境可觀測性的建議 backend。 ClickHouse 最常在[複合儲存空間](https://mastra.zisheng.pro/zh-TW/reference/storage/composite)設定中作為專用可觀測性 backend,並由另一個資料庫處理其餘 domain。 ## 適合使用 ClickHouse 的時機 在正式環境中儲存 Trace、log、metric、分數與意見回饋等可觀測性資料。 進行本機開發時,請使用結合 [LibSQL](https://mastra.zisheng.pro/zh-TW/reference/storage/libsql)(用於記憶體與 Workflow)和 `@mastra/duckdb`(用於可觀測性)的複合 store。兩者單獨使用都無法涵蓋完整開發設定:LibSQL 未實作 observability domain,而 DuckDB 未實作其他 domain。範例請參閱[可觀測性概觀](https://mastra.zisheng.pro/zh-TW/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 伺服器。受管理與自行託管選項請參閱[託管選項](#hosting-options)。 ## 使用方式 ### 搭配 vNext 使用可觀測性(建議) `ObservabilityStorageClickhouseVNext` 是目前的 observability domain 實作。它使用以 `ReplacingMergeTree` 為基礎的 insert-only schema,並針對 Trace、log、metric、分數與意見回饋所產生的資料量進行最佳化。 將它與其他儲存 adapter 組合使用,避免可觀測性寫入與應用程式資料相互競爭: ```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 作為可觀測性 backend 時,`MastraStorageExporter` 會自動選擇 `insert-only` 策略,以提供最高寫入吞吐量。詳情請參閱 [tracing strategy](https://mastra.zisheng.pro/zh-TW/docs/observability/integrations/exporters/mastra-storage)。 ### 搭配舊版 domain 使用可觀測性 `ObservabilityStorageClickhouse` 是原始可觀測性 adapter,尚未遷移至 vNext schema 的專案仍可使用。其設定結構與 vNext 類別相同。 ```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`。 ### 從舊版遷移至 vNext 若要將歷史 span 從舊版 `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 ``` Migration 會以一天為單位,將 span 資料從 `mastra_ai_spans` 複製到 `mastra_span_events`。它會處理欄位對應,並將舊版資料列去重複。原始資料表會保留作為備份。遷移後,Trace 會透過 vNext adapter 顯示在 Studio 中。 > **備註:** 系統不會刪除舊版資料表。請在確認遷移結果後手動刪除。 ### 為所有 domain 使用 ClickHouse `ClickhouseStoreVNext` 使用 ClickHouse 支援 `memory`、`workflows` 與 `observability` domain,並自動採用 vNext 可觀測性 adapter。若希望整個應用程式都由 ClickHouse 支援,而不想手動連接複合 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` 是長期使用的類別,透過舊版可觀測性 adapter 支援每個 domain。新專案應優先使用 `ClickhouseStoreVNext`。若需要自訂複合儲存空間(例如以不同 backend 覆寫某個 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 需要請求逾時、壓縮或 interceptor 等自訂連線設定時,請傳入預先設定的 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 伺服器 URL(例如 https\://your-instance.clickhouse.cloud:8443 或 http\://localhost:8123)。未傳入預先設定的 client 時為必填。 **username** (`string`): ClickHouse 使用者名稱。未傳入預先設定的 client 時為必填。 **password** (`string`): ClickHouse 密碼。未傳入預先設定的 client 時為必填。本機執行個體的預設使用者可以使用空字串。 **client** (`ClickHouseClient`): 來自 @clickhouse/client、預先設定的 ClickHouse client。需要自訂請求設定時使用。與上述 credential 欄位互斥。 **ttl** (`object`): 建立資料表時套用的各資料表 TTL 設定。接受資料列與欄位層級的 TTL,間隔單位可從 NANOSECOND 到 YEAR。 **replication** (`{ cluster?: string; zookeeperPath?: string; replicaName?: string }`): 用於多 replica ClickHouse cluster 的選用複寫資料表設定。設定後,Mastra 會建立複寫的 MergeTree 資料表。設定 cluster 時,Mastra 也會將 ON CLUSTER 新增至 Mastra 擁有的資料定義語言(DDL)。 **disableInit** (`boolean`): 設為 true 時,store 不會在首次使用時建立資料表或執行 migration。請從部署 script 明確呼叫 storage.init()。 (Default: `false`) `ClickhouseStore` 也接受 `ClickHouseClientConfigOptions` 的所有選項(例如 `database`、`request_timeout`、`compression`、`keep_alive` 與 `max_open_connections`)。 ### 複寫 cluster Mastra 透過 load balancer 寫入多 replica 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` 資料表 engine 改寫為 `ReplicatedMergeTree` 與 `ReplicatedReplacingMergeTree`。預設 engine 引數為: - `zookeeperPath`: `'/clickhouse/tables/{shard}/{database}/{table}'` - `replicaName`: `'{replica}'` 預設值符合最常見的自主管理慣例。若 cluster 的現有資料表使用不同版面設定(例如不含 `{database}` 區段的 `/clickhouse/tables/{shard}/{table}`),請明確設定相符的 `zookeeperPath`。Mastra 不會從 Keeper 讀取 cluster 慣例,因此不相符的預設值會將 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、欄位 migration、TTL 變更與刪除資料表。 設定 `cluster` 時,`optimizeTable()` 與 `materializeTtl()` 等手動維護會在每個 replica 上執行。這些操作在大型 cluster 上可能耗費大量資源。建議避開尖峰時間執行,並讓例行 merge 在背景 merge queue 上發生,不要在每次重新啟動時觸發。 若現有 Mastra 資料表使用本機 `MergeTree` 或 `ReplacingMergeTree` engine,在啟用 `replication` 時初始化會失敗。由於跨 replica 執行複製後交換並不安全,Mastra 不會默默轉換本機資料表。請先將受影響的資料表重新建立為 `Replicated*`,再啟用 replication。若要安全遷移,請重新命名本機資料表、執行 `CREATE TABLE ... ENGINE = ReplicatedMergeTree(...) ON CLUSTER ...`、執行 `INSERT INTO ... SELECT * FROM `,最後刪除 ``。 請勿在 ClickHouse Cloud 上設定 `replication`。Cloud 會在 server 端將 `MergeTree` 改寫為 `SharedMergeTree`,明確使用 `ReplicatedMergeTree` engine 會產生不正確的 DDL。`replication` 僅適用於自主管理的多 replica cluster。 ### Observability domain 選項 `ObservabilityStorageClickhouse` 與 `ObservabilityStorageClickhouseVNext` 接受和 `ClickhouseStore` 相同的連線選項(`url`、`username`、`password` 或預先設定的 `client`)。 ## 託管選項 ClickHouse 可在任何能透過 HTTP 連線的位置執行。常見選項包括: - **[ClickHouse Cloud](https://clickhouse.com/cloud)**:提供免費試用方案的受管理服務。提供與 `url`、`username` 和 `password` 直接相容的連線詳細資料。 - **自行託管**:執行官方 [`clickhouse/clickhouse-server`](https://hub.docker.com/r/clickhouse/clickhouse-server) container,或從[官方套件](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 等平台會在暫時性檔案系統上執行應用程式 container。DuckDB 等嵌入式可觀測性 backend 需要可寫入且持久的本機檔案,因此在這些平台上重新啟動時會遺失資料,或完全無法部署。 請改用 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()], }, }, }), }) ``` 使用下列任一選項佈建資料庫: - **受管理**:使用 ClickHouse Cloud。將 `CLICKHOUSE_URL`、`CLICKHOUSE_USERNAME` 與 `CLICKHOUSE_PASSWORD` 設為託管平台中的環境變數。 - **在 Railway 自行託管**:使用官方 Docker image 將 ClickHouse 服務新增至 Railway 專案,再透過 Railway 私有網路從應用程式服務參照該服務。 相同方式也適用於其他採用暫時性檔案系統的 host。若應用程式資料也應存放在 host 外,請將此設定與受管理的 PostgreSQL 或 LibSQL/Turso 執行個體搭配,作為 `default` storage。 > **警告:** 請勿將 DuckDB 等嵌入式 backend 指向暫時性 container 檔案系統內的路徑。container 重新啟動時,寫入該處的資料會遺失;在部分平台上,該路徑還是唯讀的。 ## 初始化 傳入 `Mastra` 類別時,`ClickhouseStore` 會自動呼叫 `init()` 來建立 schema,並執行任何待處理的 migration。透過 `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 pipeline 中,請在 `ClickhouseStore` 上設定 `disableInit: true`,並從使用較高權限 credential 的部署步驟執行 `init()`。之後,runtime 應用程式 credential 可限制為讀取與插入權限。 ## 可觀測性 ClickHouse 是正式環境可觀測性的建議 backend: - **Insert-only 策略**:`MastraStorageExporter` 會批次寫入已完成的 span,不會逐一更新 span,這是可用策略中吞吐量最高者。 - **欄式壓縮**:相較於列式資料庫中的相同資料,span attribute 與 log payload 可獲得良好壓縮效果。 如需完整策略矩陣與正式環境指南,請參閱 [`MastraStorageExporter` 參考資料](https://mastra.zisheng.pro/zh-TW/docs/observability/integrations/exporters/mastra-storage)。 ## 相關內容 - [儲存空間概觀](https://mastra.zisheng.pro/zh-TW/reference/storage/overview) - [複合儲存空間](https://mastra.zisheng.pro/zh-TW/reference/storage/composite) - [`MastraStorageExporter`](https://mastra.zisheng.pro/zh-TW/docs/observability/integrations/exporters/mastra-storage) - [可觀測性概觀](https://mastra.zisheng.pro/zh-TW/docs/observability/overview)