Google Cloud Spanner 스토리지
Google Cloud Spanner 스토리지 구현은 Mastra를 위한 수평적 고용량의 강력하고 일관된 스토리지 백엔드를 제공합니다. Cloud Spanner의 GoogleSQL 언어를 대상으로 합니다.
설치설치에 대한 직접 링크
- npm
- pnpm
- Yarn
- Bun
npm install @mastra/spanner@latest
pnpm add @mastra/spanner@latest
yarn add @mastra/spanner@latest
bun add @mastra/spanner@latest
용법용법에 대한 직접 링크
import { SpannerStore } from '@mastra/spanner'
const storage = new SpannerStore({
id: 'spanner-storage',
projectId: process.env.SPANNER_PROJECT_ID!,
instanceId: process.env.SPANNER_INSTANCE_ID!,
databaseId: process.env.SPANNER_DATABASE_ID!,
})
인스턴스와 데이터베이스가 이미 존재해야 합니다. 어댑터는 처음 사용할 때 필요한 테이블을 생성하므로 Spanner 클라이언트에 제공된 사용자 인증 정보에는 스키마 변경을 실행할 권한이 있어야 합니다. 또는 배포 단계에서 권한이 더 높은 사용자 인증 정보로 storage.init()을 한 번 실행하세요.
매개변수매개변수에 대한 직접 링크
id:
projectId?:
database를 제공하지 않는 경우 필수입니다.instanceId?:
database를 제공하지 않는 경우 필수입니다.databaseId?:
database를 제공하지 않는 경우 필수입니다.database?:
spannerOptions?:
@google-cloud/spanner 클라이언트 생성자에 전달되는 옵션입니다. 자격 증명이나 사용자 지정 엔드포인트를 설정하거나 로컬 에뮬레이터를 지정할 때 사용합니다.disableInit?:
storage.init()을 명시적으로 호출해야 합니다.skipDefaultIndexes?:
indexes?:
initMode?:
'sync'는 init() 중 누락된 테이블, 열, 인덱스를 생성합니다(기존 동작). 'validate'는 DDL을 실행하지 않고 필요한 모든 테이블, 열, 기본/사용자 지정 인덱스가 이미 존재하는지 확인하며, 누락된 항목이 있으면 형식이 지정된 사용자 오류를 발생시킵니다. 외부 프로세스(Terraform, Liquibase, 릴리스 파이프라인 등)가 스키마를 관리하고 Mastra는 검증만 수행해야 할 때 유용합니다.생성자 예생성자 예에 대한 직접 링크
SpannerStore는 여러 방법으로 인스턴스화할 수 있습니다.
import { Spanner } from '@google-cloud/spanner'
import { SpannerStore } from '@mastra/spanner'
// Using projectId / instanceId / databaseId
const store1 = new SpannerStore({
id: 'spanner-storage-1',
projectId: 'my-gcp-project',
instanceId: 'my-instance',
databaseId: 'mastra',
})
// Reusing an existing Spanner Database handle
const spanner = new Spanner({ projectId: 'my-gcp-project' })
const database = spanner.instance('my-instance').database('mastra')
const store2 = new SpannerStore({
id: 'spanner-storage-2',
database,
})
// Using the local Spanner emulator (set the SPANNER_EMULATOR_HOST env var)
process.env.SPANNER_EMULATOR_HOST = 'localhost:9010'
const store3 = new SpannerStore({
id: 'spanner-storage-emulator',
projectId: 'test-project',
instanceId: 'test-instance',
databaseId: 'test-db',
spannerOptions: { servicePath: 'localhost', port: 9010, sslCreds: undefined },
})
추가 참고사항추가 참고사항에 대한 직접 링크
스키마 관리스키마 관리에 대한 직접 링크
스토리지 어댑터는 모두 GoogleSQL 언어를 사용하여 다음 테이블을 생성합니다.
mastra_workflow_snapshot: Workflow 상태 및 실행 데이터mastra_threads: 대화 스레드mastra_messages: 개별 메시지mastra_resources: 리소스 작업 Memorymastra_scorers: 평가 점수mastra_background_tasks: 백그라운드 Tool 실행 상태mastra_agents: 간소화된 Agent 레코드(ID, 상태, 활성 버전)mastra_agent_versions: 버전이 지정된 Agent 구성 스냅샷mastra_mcp_clients/mastra_mcp_client_versions: MCP 클라이언트 구성 및 버전 기록mastra_mcp_servers/mastra_mcp_server_versions: MCP 서버 구성 및 버전 기록mastra_skills/mastra_skill_versions: Skill 레코드 및 버전이 지정된 Skill 스냅샷(지침, 참조, 스크립트, 에셋, 콘텐츠 트리)mastra_skill_blobs: SHA-256 해시를 키로 사용하며 Skill 버전 콘텐츠에 사용되는 콘텐츠 주소 지정 가능 Blob 저장소mastra_prompt_blocks/mastra_prompt_block_versions: Prompt 블록 레코드 및 버전이 지정된 콘텐츠 스냅샷(템플릿 콘텐츠, 규칙, 요청 컨텍스트 스키마)mastra_scorer_definitions/mastra_scorer_definition_versions: 채점기 정의 레코드 및 버전이 지정된 구성 스냅샷(판정 지침, Model, 점수 범위, 사전 설정 구성, 기본 샘플링)mastra_schedules/mastra_schedule_triggers: Mastra에 내장된WorkflowScheduler가 사용하는 cron 기반 Workflow 일정 및 트리거 기록mastra_workspaces/mastra_workspace_versions: Workspace 레코드 및 버전이 지정된 구성 스냅샷(파일 시스템, Sandbox, 마운트, 검색, Skill, Tool)mastra_datasets/mastra_dataset_items/mastra_dataset_versions: 평가 데이터 세트, SCD-2 버전 관리 항목 및 버전 스냅샷mastra_experiments/mastra_experiment_results: 실험 실행 및 항목별 결과mastra_favorites: 비정규화된 Agent 및 Skill에 대한 사용자별 즐겨찾기이며, 상위 레코드에서favoriteCount가 유지됨mastra_channel_installations/mastra_channel_config: 다중 플랫폼 채널 설치 및 플랫폼별 구성mastra_ai_spans: Observability를 위한 AI Trace 범위(Studio Trace UI를 구동하는 데 사용되는 Trace별 및 범위별 레코드) 테이블은 텍스트와 JSON 페이로드에STRING(MAX)를 사용하고, 그 밖에INT64,FLOAT64,BOOL,TIMESTAMP를 사용하여 생성됩니다. 다음 Spanner 관련 테이블에는 어댑터가 JSON 페이로드에서 채우는STORED생성 열이 포함되어 있어, 일반적인 필터에서JSON_VALUE스캔 대신 일반 보조 인덱스를 사용할 수 있습니다.mastra_workflow_snapshot.snapshotStatus:snapshot에서$.status를 추출합니다.listWorkflowRuns({ status })를 지원합니다.mastra_schedules.target_workflow_id:target에서$.workflowId를 추출합니다.listSchedules({ workflowId })를 지원합니다. 두 열 모두init()중ALTER TABLE ... ADD COLUMN IF NOT EXISTS를 통해 추가되며, 스키마를 외부에서 관리하는initMode: 'validate'에서는 건너뜁니다. 열이 없으면 어댑터는 런타임에JSON_VALUE필터로 대체합니다. 어댑터는 스키마를 생성하거나 사용하지 않습니다. 격리를 위해 전용 데이터베이스를 사용합니다.
초기화초기화에 대한 직접 링크
저장소를 Mastra 클래스에 전달하면 저장소 작업 전에 init()이 자동으로 호출됩니다.
import { Mastra } from '@mastra/core'
import { SpannerStore } from '@mastra/spanner'
const storage = new SpannerStore({
id: 'spanner-storage',
projectId: process.env.SPANNER_PROJECT_ID!,
instanceId: process.env.SPANNER_INSTANCE_ID!,
databaseId: process.env.SPANNER_DATABASE_ID!,
})
const mastra = new Mastra({
storage, // init() is called automatically
})
스토리지를 직접 사용하는 경우 첫 번째 작업 전에 init()을 한 번 호출하세요. Spanner는 동시 스키마 변경을 허용하지 않으므로 SpannerStore.init()은 각 도메인의 설정을 순차적으로 실행합니다.
const storage = new SpannerStore({
id: 'spanner-storage',
projectId: process.env.SPANNER_PROJECT_ID!,
instanceId: process.env.SPANNER_INSTANCE_ID!,
databaseId: process.env.SPANNER_DATABASE_ID!,
})
await storage.init()
const memory = await storage.getStore('memory')
const thread = await memory?.getThreadById({ threadId: '...' })
init()을 호출하지 않고 disableInit이 true이면 필요한 테이블이 존재하지 않아 저장소 작업이 실패합니다.
GoogleSQL 세부사항GoogleSQL 세부사항에 대한 직접 링크
몇 가지 동작이 다른 관계형 어댑터와 다릅니다.
- Upsert는
INSERT OR UPDATE를 사용합니다. Spanner는 upsert에RETURNING절을 제공하지 않으므로 쓰기 후 상태가 필요한 호출자는 이를 다시 읽어야 합니다. TRUNCATE는 존재하지 않습니다.dangerouslyClearAll()은DELETE WHERE TRUE를 실행합니다.- 식별자는 백틱으로 묶습니다.
- DDL은 비동기 장기 실행 작업인
database.updateSchema(...)를 통해 적용됩니다. NULLS FIRST/LAST는 지원되지 않습니다. NULL 처리가 포함된 정렬은IS NULL정렬 키를 통해 에뮬레이션됩니다.- JSON 포함 연산은 기본적으로 지원되지 않습니다.
listTraces의metadata및scope필터는 키별JSON_VALUE(...) = @v동등성 검사로 컴파일되고,tags필터는JSON_QUERY_ARRAY(...)에 대한EXISTS로 컴파일됩니다. 이는 단일 인덱스 스캔에서 중첩 구조를 일치시킬 수 있는 Postgres의@>포함 연산자와 다릅니다. 대부분의 일회성 조회는 계속 작동하지만 깊이 중첩된 구조 일치는 표현할 수 없습니다.
직접 데이터베이스 액세스직접 데이터베이스 액세스에 대한 직접 링크
SpannerStore기본 Spanner 클라이언트 객체를 노출합니다.
store.database // @google-cloud/spanner Database
store.instance // @google-cloud/spanner Instance (when created internally)
store.spanner // @google-cloud/spanner Spanner client (when created internally)
이는 맞춤형 트랜잭션이나 스키마 검사와 같은 고급 시나리오를 위한 것입니다. 데이터베이스를 직접 재사용하는 경우 어댑터의 유효성 검사 및 JSON 변환 논리를 우회합니다.
에뮬레이터를 사용한 로컬 개발에뮬레이터를 사용한 로컬 개발에 대한 직접 링크
Docker를 사용하여 Cloud Spanner 에뮬레이터를 로컬에서 실행합니다.
docker run -p 9010:9010 -p 9020:9020 gcr.io/cloud-spanner-emulator/emulator
SPANNER_EMULATOR_HOST=localhost:9010을 설정하고 앱을 실행하기 전에 인스턴스와 데이터베이스를 생성하세요.
gcloud spanner instances create test-instance --config=emulator-config --nodes=1
gcloud spanner databases create test-db --instance=test-instance
그런 다음 Node.js 프로세스에 동일한 환경 변수를 설정하여 연결하세요. @google-cloud/spanner 클라이언트가 에뮬레이터를 자동으로 감지합니다.