ClickHouse 儲存
ClickHouse 是專為分析工作負載而設計的欄式數據庫。@mastra/clickhouse 套件為多個 Mastra 儲存領域提供儲存適配器,亦是生產環境可觀測性建議使用的後端。
ClickHouse 最常在複合儲存設定中用作專用可觀測性後端,並由另一個數據庫處理其餘領域。
何時使用 ClickHouse何時使用 ClickHouse 的直接連結
用於 trace、日誌、指標、評分及意見回饋的生產環境可觀測性。
在本機開發時,請使用結合 LibSQL(用於 memory 及 workflow)與 @mastra/duckdb(用於可觀測性)的複合儲存。兩者均無法單獨涵蓋開發設定:LibSQL 未有實作可觀測性領域,而 DuckDB 則未有實作其他領域。例子請參閱可觀測性概覽。
安裝安裝 的直接連結
- npm
- pnpm
- Yarn
- Bun
npm install @mastra/clickhouse@latest
pnpm add @mastra/clickhouse@latest
yarn add @mastra/clickhouse@latest
bun add @mastra/clickhouse@latest
你亦需要一個正在運行的 ClickHouse 伺服器。有關託管及自行託管的選擇,請參閱託管選項。
使用方式使用方式 的直接連結
配合 vNext 使用可觀測性(建議)配合 vNext 使用可觀測性(建議) 的直接連結
ObservabilityStorageClickhouseVNext 是目前的可觀測性領域實作。它使用由 ReplacingMergeTree 支援的純插入 schema,並針對 trace、日誌、指標、評分及意見回饋所產生的數據量作出最佳化。
將它與另一個儲存適配器組合使用,令可觀測性寫入不會與應用程式數據爭用資源:
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 是可觀測性後端時,MastraStorageExporter 會自動選擇 insert-only 策略,以提供最高的寫入吞吐量。詳情請參閱 tracing 策略。
配合舊有領域使用可觀測性配合舊有領域使用可觀測性 的直接連結
ObservabilityStorageClickhouse 是原有的可觀測性適配器,尚未遷移至 vNext schema 的項目仍可繼續使用。其設定格式與 vNext class 相同。
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從舊有版本遷移至 vNext 的直接連結
要將歷史 span 從舊有的 mastra_ai_spans 資料表遷移至 vNext schema,請執行:
- npm
- pnpm
- Yarn
- Bun
npx mastra migrate
pnpm dlx mastra migrate
yarn dlx mastra migrate
bun x mastra migrate
遷移會以每日為一個批次,將 span 數據從 mastra_ai_spans 複製至 mastra_span_events。過程會處理欄位映射,並為舊有資料列去除重複項目。原有資料表會保留作備份。遷移後,trace 會透過 vNext 適配器顯示於 Studio。
舊有資料表不會被刪除。確認遷移成功後,請手動將其移除。
所有領域均使用 ClickHouse所有領域均使用 ClickHouse 的直接連結
ClickhouseStoreVNext 使用 ClickHouse 支援 memory、workflows 及 observability 領域,並自動採用 vNext 可觀測性適配器。如果你希望整個應用程式均由 ClickHouse 支援,而毋須手動連接複合儲存,便可使用它。
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 相同的設定,並在所有領域重用同一個 ClickHouse client。
手動組合手動組合 的直接連結
ClickhouseStore 是長期使用的 class,以舊有可觀測性適配器支援所有領域。新項目應優先選用 ClickhouseStoreVNext。如需自訂複合儲存(例如以不同後端覆寫其中一個領域),請手動建立:
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使用你自己的 ClickHouse client 的直接連結
如需自訂連線設定,例如請求逾時、壓縮或 interceptor,請傳入預先設定的 client:
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 選項clickhousestore-options 的直接連結
id:
url?:
https://your-instance.clickhouse.cloud:8443 或 http://localhost:8123)。如未傳入預先設定的 client,此項為必填。username?:
client,此項為必填。password?:
client,此項為必填。本機實例的預設使用者可使用空字串。client?:
@clickhouse/client 並已預先設定的 ClickHouse client。需要自訂請求設定時使用。不可與上述憑證欄位同時使用。ttl?:
NANOSECOND 至 YEAR 為間隔單位的資料列層級及欄位層級 TTL。replication?:
cluster 後,Mastra 亦會在由 Mastra 管理的資料定義語言(DDL)中加入 ON CLUSTER。disableInit?:
true 時,儲存不會在首次使用時建立資料表或執行遷移。請從部署指令碼明確呼叫 storage.init()。ClickhouseStore 亦接受 ClickHouseClientConfigOptions 的所有選項(例如 database、request_timeout、compression、keep_alive 及 max_open_connections)。
複寫叢集複寫叢集 的直接連結
當 Mastra 透過負載平衡器寫入多副本 ClickHouse 叢集時,請使用 replication。
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 資料表引擎改寫為 ReplicatedMergeTree 及 ReplicatedReplacingMergeTree。預設引擎引數如下:
zookeeperPath:'/clickhouse/tables/{shard}/{database}/{table}'replicaName:'{replica}'
這些預設值符合最常見的自行管理慣例。如果叢集的現有資料表採用不同配置(例如 /clickhouse/tables/{shard}/{table},當中不含 {database} 部分),請明確設定 zookeeperPath 以保持一致。Mastra 不會從 Keeper 讀取叢集的慣例,因此不相符的預設值會將 Mastra 的中繼資料寫入與叢集其餘部分分開的分支。
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,即可在由 Mastra 管理的 DDL 中加入 ON CLUSTER,包括建立資料表、建立 materialized view、欄位遷移、更改 TTL 及移除資料表。
設定 cluster 後,optimizeTable() 及 materializeTtl() 等手動維護工作會在每個副本上執行。在大型叢集上,這些操作可能耗用大量資源。建議在非繁忙時段執行,並讓例行合併在背景合併佇列中進行,避免每次重新啟動時均觸發有關操作。
如現有 Mastra 資料表使用本機 MergeTree 或 ReplacingMergeTree 引擎,啟用 replication 後初始化便會失敗。Mastra 不會在未有提示的情況下轉換本機資料表,因為在副本之間執行複製再交換並不安全。要進行遷移,請在啟用複寫前,將受影響的資料表重新建立為 Replicated*。安全的遷移方式是重新命名本機資料表,執行 CREATE TABLE ... ENGINE = ReplicatedMergeTree(...) ON CLUSTER ...,再執行 INSERT INTO ... SELECT * FROM <renamed_local>,然後移除 <renamed_local>。
請勿在 ClickHouse Cloud 上設定 replication。Cloud 會在伺服器端將 MergeTree 改寫為 SharedMergeTree,而明確指定 ReplicatedMergeTree 引擎會產生不正確的 DDL。replication 僅適用於自行管理的多副本叢集。
可觀測性領域選項可觀測性領域選項 的直接連結
ObservabilityStorageClickhouse 及 ObservabilityStorageClickhouseVNext 接受與 ClickhouseStore 相同的連線選項(url、username、password,或預先設定的 client)。
託管選項託管選項 的直接連結
只要能透過 HTTP 連接,ClickHouse 便可在任何地方運行。常見選擇包括:
- ClickHouse Cloud:設有免費試用級別的託管服務。提供可直接配合
url、username及password使用的連線資料。 - 自行託管:運行官方
clickhouse/clickhouse-server容器,或從官方套件安裝。適用於 VPS、專用硬件或 Kubernetes。
本機開發設定:
docker run -d --name mastra-clickhouse \
-p 8123:8123 -p 9000:9000 \
-e CLICKHOUSE_USER=default \
-e CLICKHOUSE_PASSWORD=password \
clickhouse/clickhouse-server
new ObservabilityStorageClickhouseVNext({
url: 'http://localhost:8123',
username: 'default',
password: 'password',
})
部署至 Railway 及類似平台部署至 Railway 及類似平台 的直接連結
Railway、Fly.io、Render 及 Heroku 等平台在暫存檔案系統上運行應用程式容器。DuckDB 等嵌入式可觀測性後端需要可寫入且持久的本機檔案,因此在這些平台上重新啟動時會遺失數據,或完全無法部署。
請改用 ClickHouse。由於 ClickHouse 透過 HTTP 連接,因此同一個連線可在任何主機上使用:
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 映像,在 Railway 項目中加入 ClickHouse 服務,然後透過 Railway 的私人網絡在應用程式服務中參照該服務。
同一種做法亦適用於其他使用暫存檔案系統的主機。如果應用程式數據亦應儲存於主機以外的位置,請將此設定配合受管理的 PostgreSQL 或 LibSQL/Turso 實例,作為 default 儲存。
請勿將 DuckDB 等嵌入式後端指向暫存容器檔案系統內的路徑。容器重新啟動時,寫入該處的數據會遺失,而在部分平台上該路徑更是唯讀。
初始化初始化 的直接連結
傳入 Mastra class 後,ClickhouseStore 會自動呼叫 init() 來建立 schema,並執行任何待處理的遷移。透過 MastraCompositeStore 使用 ObservabilityStorageClickhouseVNext 時亦一樣。
如你在 Mastra 以外管理儲存,請明確呼叫 init():
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,並從使用較高權限憑證的部署步驟執行 init()。之後便可將執行階段應用程式憑證限制為讀取及插入權限。
可觀測性可觀測性 的直接連結
ClickHouse 是生產環境可觀測性建議使用的後端:
- 純插入策略:
MastraStorageExporter會分批寫入已完成的 span,而不會逐一更新 span,是現有策略中吞吐量最高的一種。 - 欄式壓縮:與資料列導向數據庫中的相同數據相比,span 屬性及日誌 payload 可獲得更佳壓縮效果。
如需完整策略矩陣及生產環境指引,請參閱 MastraStorageExporter 參考。