> Discover all available pages from the documentation index: https://mastra.zisheng.pro/ko/llms.txt # 복합 스토리지 `MastraCompositeStore`다양한 공급자로부터 스토리지 도메인을 구성할 수 있습니다. 다양한 목적을 위해 다양한 데이터베이스가 필요할 때 사용하세요. 예를 들어 Memory에는 LibSQL을 사용하고 Workflow에는 PostgreSQL을 사용합니다. ## 설치 `MastraCompositeStore`에 포함되어 있습니다`@mastra/core`: **npm**: ```bash npm install @mastra/core@latest ``` **pnpm**: ```bash pnpm add @mastra/core@latest ``` **Yarn**: ```bash yarn add @mastra/core@latest ``` **Bun**: ```bash bun add @mastra/core@latest ``` 구성하려는 스토리지 공급자도 설치해야 합니다. **npm**: ```bash npm install @mastra/pg@latest @mastra/libsql@latest @mastra/mongodb@latest ``` **pnpm**: ```bash pnpm add @mastra/pg@latest @mastra/libsql@latest @mastra/mongodb@latest ``` **Yarn**: ```bash yarn add @mastra/pg@latest @mastra/libsql@latest @mastra/mongodb@latest ``` **Bun**: ```bash bun add @mastra/pg@latest @mastra/libsql@latest @mastra/mongodb@latest ``` ## 스토리지 도메인 Mastra는 스토리지를 도메인으로 구성하고 각 도메인은 특정 유형의 데이터를 처리합니다. 각 도메인은 서로 다른 스토리지 어댑터로 지원될 수 있으며 도메인 클래스는 각 스토리지 패키지에서 내보내집니다. | 도메인 | 설명 | | --------------- | --------------------------------------------------------------------------------------------------------- | | `memory` | Agent의 대화 지속성을 관리합니다. 스레드(대화 세션), 메시지, 리소스(사용자 ID), 작업 Memory(대화 간에 유지되는 컨텍스트)를 저장합니다. | | `workflows` | Workflow 실행 상태입니다. 사람의 입력, 외부 이벤트 또는 예약된 재개를 위해 Workflow가 일시 중단되면 서버가 다시 시작된 후에도 재개할 수 있도록 상태가 여기에 유지됩니다. | | `scores` | Mastra Evals 시스템의 평가 결과입니다. 시간 경과에 따른 분석과 비교를 위해 점수와 지표가 여기에 유지됩니다. | | `observability` | Trace와 스팬을 포함한 원격 분석 데이터입니다. Agent 상호 작용, Tool 호출, LLM 요청은 디버깅과 성능 분석을 위해 Trace로 수집되는 스팬을 생성합니다. | | `agents` | 저장된 Agent의 구성입니다. 코드를 배포하지 않고도 런타임에 Agent를 정의하고 업데이트할 수 있습니다. | | `datasets` | 실험 실행에 사용되는 평가 데이터세트입니다. 데이터세트 정의, 스키마, 버전이 지정된 항목을 저장합니다. | | `experiments` | 데이터세트 및 대상에 연결된 실험 실행과 항목별 실험 결과입니다. | > **노트:** `MastraCompositeStore`는 위의 모든 도메인 키를 허용하지만, 스토리지 어댑터 지원 범위는 패키지마다 다릅니다. 도메인별로 어댑터를 조합할 수 있지만, 해당 어댑터가 구현하고 내보내는 도메인에만 사용할 수 있습니다. 예를 들어 두 패키지가 모두 해당 도메인 클래스를 내보내므로 `memory: new MemoryLibSQL(...)`과 `workflows: new WorkflowsPG(...)`을 함께 사용하는 것은 유효합니다. ## 용법 ### 기본구성 각 스토어 패키지에서 직접 도메인 클래스를 가져와 구성합니다. ```typescript import { MastraCompositeStore } from '@mastra/core/storage' import { WorkflowsPG, ScoresPG } from '@mastra/pg' import { MemoryLibSQL } from '@mastra/libsql' import { Mastra } from '@mastra/core' export const mastra = new Mastra({ storage: new MastraCompositeStore({ id: 'composite', domains: { memory: new MemoryLibSQL({ url: 'file:./local.db' }), workflows: new WorkflowsPG({ connectionString: process.env.DATABASE_URL }), scores: new ScoresPG({ connectionString: process.env.DATABASE_URL }), }, }), }) ``` ### 기본 저장소 사용 `default`를 사용하여 대체 스토리지를 지정한 다음 특정 도메인을 재정의하세요. ```typescript import { MastraCompositeStore } from '@mastra/core/storage' import { PostgresStore } from '@mastra/pg' import { MemoryLibSQL } from '@mastra/libsql' import { Mastra } from '@mastra/core' const pgStore = new PostgresStore({ id: 'pg', connectionString: process.env.DATABASE_URL, }) export const mastra = new Mastra({ storage: new MastraCompositeStore({ id: 'composite', default: pgStore, domains: { memory: new MemoryLibSQL({ url: 'file:./local.db' }), }, }), }) ``` ### 혼합 백엔드 각 스토리지 패키지의 도메인 클래스를 사용하여 다양한 도메인을 다양한 백엔드로 라우팅합니다. 다음 예에서는 MongoDB에 Memory와 Workflow 상태를 저장한 다음 Observability을 ClickHouse로 라우팅합니다. ```typescript import { Mastra } from '@mastra/core' import { MastraCompositeStore } from '@mastra/core/storage' import { ObservabilityStorageClickhouse } from '@mastra/clickhouse' import { MemoryStorageMongoDB, WorkflowsStorageMongoDB } from '@mastra/mongodb' export const mastra = new Mastra({ storage: new MastraCompositeStore({ id: 'composite', domains: { memory: new MemoryStorageMongoDB({ uri: process.env.MONGODB_URI, dbName: 'mastra_memory', }), workflows: new WorkflowsStorageMongoDB({ uri: process.env.MONGODB_URI, dbName: 'mastra_workflows', }), observability: new ObservabilityStorageClickhouse({ url: process.env.CLICKHOUSE_URL, username: process.env.CLICKHOUSE_USERNAME, password: process.env.CLICKHOUSE_PASSWORD, }), }, }), }) ``` ### 도메인 비활성화 도메인을 `false`로 설정하면 비활성화됩니다. 비활성화된 도메인은 `default`로 대체되지 않으므로 해당 도메인의 데이터가 유지되지 않습니다. ```typescript import { MastraCompositeStore } from '@mastra/core/storage' import { PostgresStore } from '@mastra/pg' import { Mastra } from '@mastra/core' const pgStore = new PostgresStore({ id: 'pg', connectionString: process.env.DATABASE_URL, }) export const mastra = new Mastra({ storage: new MastraCompositeStore({ id: 'composite', default: pgStore, domains: { // don't persist traces and spans observability: false, }, }), }) ``` ## 옵션 **id** (`string`): 이 스토리지 인스턴스의 고유 식별자입니다. **default** (`MastraCompositeStore`): 기본 스토리지 어댑터입니다. domains에 명시적으로 지정되지 않은 도메인은 이 스토리지의 도메인을 대체 항목으로 사용합니다. **editor** (`MastraCompositeStore`): Agent, Prompt 블록, 채점기, MCP 클라이언트와 서버, Workspace, Skill을 포함하여 Editor가 소유한 도메인의 스토리지 어댑터입니다. 기본 스토리지보다 우선하지만 명시적인 도메인 재정의보다 우선하지는 않습니다. **disableInit** (`boolean`): true이면 자동 초기화가 비활성화됩니다. init()을 명시적으로 호출해야 합니다. **domains** (`object`): 개별 도메인 재정의입니다. 각 도메인은 서로 다른 스토리지 어댑터에서 가져올 수 있습니다. 이러한 재정의는 editor와 default 스토리지보다 모두 우선합니다. 도메인을 false로 설정하면 완전히 비활성화되며, 비활성화된 도메인은 editor나 default로 대체되지 않습니다. **domains.memory** (`MemoryStorage`): 스레드, 메시지, 리소스를 위한 스토리지입니다. **domains.workflows** (`WorkflowsStorage`): Workflow 스냅샷을 위한 스토리지입니다. **domains.scores** (`ScoresStorage`): 평가 점수를 위한 스토리지입니다. **domains.observability** (`ObservabilityStorage`): Trace와 스팬을 위한 스토리지입니다. **domains.agents** (`AgentsStorage`): 저장된 Agent 구성을 위한 스토리지입니다. **domains.datasets** (`DatasetsStorage`): 데이터세트 메타데이터, 데이터세트 항목, 데이터세트 버전을 위한 스토리지입니다. **domains.experiments** (`ExperimentsStorage`): 실험 실행과 항목별 실험 결과를 위한 스토리지입니다. ## 초기화 `MastraCompositeStore`는 구성된 각 도메인을 독립적으로 초기화합니다. Mastra 클래스에 전달하면 `init()`이 자동으로 호출됩니다. ```typescript import { MastraCompositeStore } from '@mastra/core/storage' import { MemoryPG, WorkflowsPG, ScoresPG } from '@mastra/pg' import { Mastra } from '@mastra/core' const storage = new MastraCompositeStore({ id: 'composite', domains: { memory: new MemoryPG({ connectionString: process.env.DATABASE_URL }), workflows: new WorkflowsPG({ connectionString: process.env.DATABASE_URL }), scores: new ScoresPG({ connectionString: process.env.DATABASE_URL }), }, }) export const mastra = new Mastra({ storage, // init() called automatically }) ``` 저장소를 직접 사용하는 경우`init()` explicitly: ```typescript import { MastraCompositeStore } from '@mastra/core/storage' import { MemoryPG } from '@mastra/pg' const storage = new MastraCompositeStore({ id: 'composite', domains: { memory: new MemoryPG({ connectionString: process.env.DATABASE_URL }), }, }) await storage.init() // Access domain-specific stores via getStore() const memoryStore = await storage.getStore('memory') const thread = await memoryStore?.getThreadById({ threadId: '...' }) ``` ## 연결 종료 `close()`는 복합 스토리지가 생성한 `default` 및 `editor` 스토어와 자체 클라이언트를 소유한 모든 도메인의 연결을 해제합니다. 하나의 스토어가 여러 도메인을 지원하더라도 각 스토어는 한 번만 닫힙니다. Mastra 클래스에 전달하면 `shutdown()`이 `close()`를 호출합니다. ```typescript import { MastraCompositeStore } from '@mastra/core/storage' import { PostgresStore } from '@mastra/pg' import { Mastra } from '@mastra/core' const pgStore = new PostgresStore({ id: 'pg-storage', connectionString: process.env.DATABASE_URL, }) export const mastra = new Mastra({ storage: new MastraCompositeStore({ id: 'composite', default: pgStore }), }) process.on('SIGTERM', async () => { // Releases the Postgres pool, so the process can exit await mastra.shutdown() }) ``` 도메인을 제공하기 위해서만 구성한 저장소는 복합을 통해 연결할 수 없습니다. 이에 대한 참조를 유지하고 직접 닫으십시오. ```typescript import { MastraCompositeStore } from '@mastra/core/storage' import { ClickhouseStore } from '@mastra/clickhouse' import { PostgresStore } from '@mastra/pg' import { Mastra } from '@mastra/core' const pgStore = new PostgresStore({ id: 'pg-storage', connectionString: process.env.DATABASE_URL, }) const clickhouseStore = new ClickhouseStore({ id: 'clickhouse-storage', 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', default: pgStore, domains: { observability: clickhouseStore.stores?.observability }, }), }) process.on('SIGTERM', async () => { await mastra.shutdown() await clickhouseStore.close() }) ``` ## 사용 사례 ### 다양한 워크로드를 위한 별도의 데이터베이스 관리형 서비스에 프로덕션 데이터를 유지하면서 개발을 위해 로컬 데이터베이스를 사용합니다. ```typescript import { MastraCompositeStore } from '@mastra/core/storage' import { MemoryPG, WorkflowsPG, ScoresPG } from '@mastra/pg' import { MemoryLibSQL } from '@mastra/libsql' const storage = new MastraCompositeStore({ id: 'composite', domains: { // Use local SQLite for development, PostgreSQL for production memory: process.env.NODE_ENV === 'development' ? new MemoryLibSQL({ url: 'file:./dev.db' }) : new MemoryPG({ connectionString: process.env.DATABASE_URL }), workflows: new WorkflowsPG({ connectionString: process.env.DATABASE_URL }), scores: new ScoresPG({ connectionString: process.env.DATABASE_URL }), }, }) ``` ### Observability을 위한 특수 스토리지 Observability 데이터는 프로덕션 환경에서 범용 데이터베이스를 빠르게 압도할 수 있습니다. 단일 Agent 상호 작용으로 수백 개의 범위가 생성될 수 있으며 트래픽이 많은 애플리케이션은 하루에 수천 개의 추적을 생성할 수 있습니다. **[클릭하우스](https://mastra.zisheng.pro/ko/reference/storage/clickhouse)**대용량, 쓰기 집약적 분석 워크로드에 최적화되어 있으므로 프로덕션 Observability에 권장됩니다. 기본 데이터베이스에 다른 데이터를 유지하면서 복합 스토리지를 사용하여 Observability을 ClickHouse로 라우팅합니다. ```typescript import { MastraCompositeStore } from '@mastra/core/storage' import { MemoryPG, WorkflowsPG, ScoresPG } from '@mastra/pg' import { ObservabilityStorageClickhouseVNext } from '@mastra/clickhouse' const storage = new MastraCompositeStore({ id: 'composite', domains: { memory: new MemoryPG({ connectionString: process.env.DATABASE_URL }), workflows: new WorkflowsPG({ connectionString: process.env.DATABASE_URL }), scores: new ScoresPG({ connectionString: process.env.DATABASE_URL }), observability: new ObservabilityStorageClickhouseVNext({ url: process.env.CLICKHOUSE_URL, username: process.env.CLICKHOUSE_USERNAME, password: process.env.CLICKHOUSE_PASSWORD, }), }, }) ``` > **노트:** `ObservabilityStorageClickhouseVNext`는 현재 Observability 도메인 구현입니다. 레거시 `ObservabilityStorageClickhouse` 클래스도 내보내며, 아직 마이그레이션하지 않은 프로젝트에서 계속 지원됩니다. 자세한 내용은 [ClickHouse 스토리지 레퍼런스](https://mastra.zisheng.pro/ko/reference/storage/clickhouse)를 참조하세요. ### 다중 복제본 클러스터를 위한 복제된 ClickHouse 복제본이 여러 개인 자체 관리형 ClickHouse 클러스터에서는 `replication`을 설정하여 Mastra가 `ReplicatedMergeTree` 엔진을 생성하고 DDL에 `ON CLUSTER`를 적용하도록 하세요. ```typescript import { MastraCompositeStore } from '@mastra/core/storage' import { MemoryPG, WorkflowsPG, ScoresPG } from '@mastra/pg' import { ObservabilityStorageClickhouseVNext } from '@mastra/clickhouse' const storage = new MastraCompositeStore({ id: 'composite', domains: { memory: new MemoryPG({ connectionString: process.env.DATABASE_URL }), workflows: new WorkflowsPG({ connectionString: process.env.DATABASE_URL }), scores: new ScoresPG({ connectionString: process.env.DATABASE_URL }), observability: new ObservabilityStorageClickhouseVNext({ url: process.env.CLICKHOUSE_URL, username: process.env.CLICKHOUSE_USERNAME, password: process.env.CLICKHOUSE_PASSWORD, replication: { cluster: 'production_cluster', // Optional (defaults shown): // zookeeperPath: '/clickhouse/tables/{shard}/{database}/{table}', // replicaName: '{replica}', }, }), }, }) ``` ClickHouse Cloud에서는 `replication`을 설정하지 마세요. Cloud가 서버 측에서 `MergeTree`를 `SharedMergeTree`로 다시 작성합니다. 전체 구성 구조와 운영자 참고 사항은 [ClickHouse 스토리지 레퍼런스](https://mastra.zisheng.pro/ko/reference/storage/clickhouse)를 참조하세요. > **정보:** 이 접근 방식은 Observability을 지원하지 않는 스토리지 Provider(예: Convex, DynamoDB 또는 Cloudflare)를 사용할 때도 필요합니다. 지원되는 Provider의 전체 목록은 [MastraStorageExporter 문서](https://mastra.zisheng.pro/ko/docs/observability/integrations/exporters/mastra-storage)를 참조하세요.