存储架构
本页从整体视角说明 Chameleon 的数据存储设计。若你需要表字段与关系细节,请优先阅读「数据库设计」章节。
文档定位
本页回答的是“存储为什么这样分层,以及三层存储如何协作”,不是字段字典或 ORM 对象手册。
如何选择:
- 想看存储分层、数据流和备份恢复:读本页
- 想看表结构、关系和索引:读 数据模式与关系
- 想看迁移策略:读 迁移与版本管理
- 想看数据库 / MinIO / Qdrant 的源码级对象参考:读 数据库与存储 API 参考
设计目标
当前存储架构围绕三件事展开:
- 保证业务元数据可追溯
- 保证向量检索可扩展
- 保证 Agent 级知识隔离
三层存储职责
| 存储层 | 技术 | 主要职责 |
|---|---|---|
| 关系型元数据层 | PostgreSQL + SQLAlchemy | 会话、消息、Agent、知识源、文档、摄取任务、文本块 |
| 向量检索层 | Qdrant | 向量索引与过滤检索 |
| 对象文件层 | MinIO | 原始文档持久化与回溯 |
关系型层是业务真相源,向量层和对象层围绕它协作。
端到端数据流
文档摄取流
flowchart LR
Upload[上传文档] --> Minio[MinIO 原始文件]
Minio --> Parser[解析器]
Parser --> Chunker[分块服务]
Chunker --> PgChunks[PostgreSQL 文本块]
Chunker --> Embedding[Embedding 服务]
Embedding --> Qdrant[Qdrant 向量索引]
Chunker --> JobState[摄取任务状态更新]
对话检索流
flowchart LR
Request[对话请求] --> Orchestrator[编排器]
Orchestrator --> Filter[按 Agent 与 Source 过滤]
Filter --> Qdrant[Qdrant 相似度检索]
Qdrant --> ChunkMeta[返回 chunk payload]
ChunkMeta --> Postgres[按 chunk_id 回查元数据]
Postgres --> Context[拼装上下文]
Context --> Orchestrator
关键设计决策
关系与向量分离
document_chunks保存文本内容与业务元信息。- Qdrant payload 保存
chunk_id、source_id、document_id、agent_id等过滤维度。 - 更换嵌入模型时只需重建向量,不需要重新上传原始文档。
Agent 作用域隔离
- Agent 与知识源通过
agent_knowledge_links建立挂载关系。 - 检索时按
agent_id和source_id过滤,限制召回范围。
异步任务可观测
ingestion_jobs记录状态机与进度计数。status_message提供当前阶段文本,便于前端实时展示。
代码入口映射
- 数据库连接:
ai_service/utils/database.py - ORM 模型与 CRUD 兼容入口:
ai_service/storage/models.py - ORM 内部实现分层:
ai_service/storage/model_domains/ - 向量服务:
ai_service/storage/qdrant_client.py - 对象存储服务:
ai_service/storage/minio_client.py - 摄取编排:
ai_service/services/ingestion.py
ai_service/storage/models.py 仍然保留为稳定导入面,方便现有服务、Alembic 与测试继续使用;实际实现已经按 domain 拆分到 ai_service/storage/model_domains/ 下,便于分别维护会话、Agent、知识源、文档、评测、技能、MCP 与任务记录。
备份与恢复策略
统一脚本入口:
scripts/backup/backup_all.shscripts/backup/restore_all.sh
备份模式
系统支持四种备份模式,通过 BACKUP_MODE 环境变量或 --mode 参数指定:
| 模式 | 说明 | 适用场景 |
|---|---|---|
tiered |
PG dump + MinIO 增量 S3 同步,跳过 Qdrant | 默认,适合 TB 级数据量的日常备份 |
hot |
PG dump + MinIO 本地导出 + Qdrant 快照,全部打包归档 | 数据量较小时的全量热备 |
cold |
停止容器后进行卷级归档 | 需要一致性快照的冷备 |
all |
先执行 hot,再执行 cold |
完整备份(耗时最长) |
分层备份策略(tiered 模式)
针对 TB 级数据量,默认采用分层备份策略以避免每日全量:
| 层 | 每日操作 | 数据量 |
|---|---|---|
| PostgreSQL | pg_dump 逻辑导出 → 加密归档 → 上传 B2 |
MB ~ GB |
| MinIO(文档) | mc mirror 增量同步到 B2(S3→S3,只传新增/变更对象) |
仅增量 |
| Qdrant(向量) | 跳过(可从 PG + 文档重建) | 0 |
恢复路径:PG dump 恢复 → B2 文档同步回 MinIO → ai-service 启动 reconciliation 重建向量。
全量备份(hot 模式)
将三层存储全部导出并打包为单个加密归档:
| 层 | 操作 | 说明 |
|---|---|---|
| PostgreSQL | pg_dump 逻辑导出 |
在线执行,不停服务 |
| MinIO(文档) | 容器内导出对象到本地暂存目录 | 全量导出 |
| Qdrant(向量) | 存储快照归档 | 全量导出 |
归档包含所有数据,恢复时直接解压导入即可,无需额外同步步骤。数据量大时归档文件会很大。
远程存储(S3 兼容)
备份归档和 MinIO 对象支持同步到 S3 兼容存储(如 Backblaze B2、AWS S3、Cloudflare R2)。通过 config.toml 的 [backup] 配置 s3_enabled、s3_endpoint、s3_bucket 等字段启用。
自动备份容器
infra 部署环境提供 backup-cron 容器,按 cron 表达式自动执行分层备份。该容器通过 Docker label 查找目标服务容器(composeless 模式),无需挂载 compose 文件。
目标恢复指标:
RPO <= 15 分钟RTO <= 30 分钟(关键路径)
延伸阅读
- 模式与关系:
docs/database/schema.md - 迁移与版本:
docs/database/migrations.md - 代码级 API:
docs/api/storage.md