mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-04-25 16:36:21 +02:00
Native CLI i18n: The TrustGraph CLI has built-in translation support that dynamically loads language strings. You can test and use different languages by simply passing the --lang flag (e.g., --lang es for Spanish, --lang ru for Russian) or by configuring your environment's LANG variable. Automated Docs Translations: This PR introduces autonomously translated Markdown documentation into several target languages, including Spanish, Swahili, Portuguese, Turkish, Hindi, Hebrew, Arabic, Simplified Chinese, and Russian.
307 lines
9 KiB
Markdown
307 lines
9 KiB
Markdown
---
|
||
layout: default
|
||
title: "向量存储生命周期管理"
|
||
parent: "Chinese (Beta)"
|
||
---
|
||
|
||
# 向量存储生命周期管理
|
||
|
||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||
|
||
## 概述
|
||
|
||
本文档描述了 TrustGraph 如何管理跨不同后端实现(Qdrant、Pinecone、Milvus)的向量存储集合。该设计解决了在不硬编码维度值的情况下,支持具有不同维度的嵌入向量的挑战。
|
||
|
||
## 问题陈述
|
||
|
||
向量存储在创建集合/索引时需要指定嵌入维度。但是:
|
||
不同的嵌入模型会产生不同的维度(例如,384、768、1536)
|
||
直到生成第一个嵌入向量,维度才已知
|
||
单个 TrustGraph 集合可能会接收来自多个模型的嵌入向量
|
||
强制指定一个维度(例如,384)会导致使用其他嵌入向量大小时出现故障
|
||
|
||
## 设计原则
|
||
|
||
1. **延迟创建**: 集合是在首次写入时按需创建的,而不是在集合管理操作期间创建的。
|
||
2. **基于维度的命名**: 集合名称包含嵌入维度作为后缀。
|
||
3. **优雅降级**: 对不存在的集合执行的查询返回空结果,而不是错误。
|
||
4. **多维度支持**: 单个逻辑集合可以有多个物理集合(每个维度一个)。
|
||
|
||
## 架构
|
||
|
||
### 集合命名约定
|
||
|
||
向量存储集合使用维度后缀来支持多种嵌入向量大小:
|
||
|
||
**文档嵌入:**
|
||
Qdrant: `d_{user}_{collection}_{dimension}`
|
||
Pinecone: `d-{user}-{collection}-{dimension}`
|
||
Milvus: `doc_{user}_{collection}_{dimension}`
|
||
|
||
**图嵌入:**
|
||
Qdrant: `t_{user}_{collection}_{dimension}`
|
||
Pinecone: `t-{user}-{collection}-{dimension}`
|
||
Milvus: `entity_{user}_{collection}_{dimension}`
|
||
|
||
示例:
|
||
`d_alice_papers_384` - Alice 的论文集合,使用 384 维的嵌入向量
|
||
`d_alice_papers_768` - 相同的逻辑集合,使用 768 维的嵌入向量
|
||
`t_bob_knowledge_1536` - Bob 的知识图谱,使用 1536 维的嵌入向量
|
||
|
||
### 生命周期阶段
|
||
|
||
#### 1. 集合创建请求
|
||
|
||
**请求流程:**
|
||
```
|
||
User/System → Librarian → Storage Management Topic → Vector Stores
|
||
```
|
||
|
||
**行为:**
|
||
库管理员将 `create-collection` 请求广播到所有存储后端。
|
||
向量存储处理器确认该请求,但**不创建物理集合**。
|
||
立即返回成功响应。
|
||
实际集合的创建将在第一次写入时延迟。
|
||
|
||
**理由:**
|
||
在创建时,维度是未知的。
|
||
避免创建具有错误维度的集合。
|
||
简化集合管理逻辑。
|
||
|
||
#### 2. 写入操作(延迟创建)
|
||
|
||
**写入流程:**
|
||
```
|
||
Data → Storage Processor → Check Collection → Create if Needed → Insert
|
||
```
|
||
|
||
**行为:**
|
||
1. 从向量中提取嵌入维度:`dim = len(vector)`
|
||
2. 使用维度后缀构建集合名称
|
||
3. 检查是否存在具有该特定维度的集合
|
||
4. 如果不存在:
|
||
创建具有正确维度的集合
|
||
记录:`"Lazily creating collection {name} with dimension {dim}"`
|
||
5. 将嵌入信息插入到特定维度的集合中
|
||
|
||
**示例场景:**
|
||
```
|
||
1. User creates collection "papers"
|
||
→ No physical collections created yet
|
||
|
||
2. First document with 384-dim embedding arrives
|
||
→ Creates d_user_papers_384
|
||
→ Inserts data
|
||
|
||
3. Second document with 768-dim embedding arrives
|
||
→ Creates d_user_papers_768
|
||
→ Inserts data
|
||
|
||
Result: Two physical collections for one logical collection
|
||
```
|
||
|
||
#### 3. 查询操作
|
||
|
||
**查询流程:**
|
||
```
|
||
Query Vector → Determine Dimension → Check Collection → Search or Return Empty
|
||
```
|
||
|
||
**行为:**
|
||
1. 从查询向量中提取维度:`dim = len(vector)`
|
||
2. 使用维度后缀构建集合名称
|
||
3. 检查集合是否存在
|
||
4. 如果存在:
|
||
执行相似度搜索
|
||
返回结果
|
||
5. 如果不存在:
|
||
记录日志:`"Collection {name} does not exist, returning empty results"`
|
||
返回空列表(不引发错误)
|
||
|
||
**同一查询中的多个维度:**
|
||
如果查询包含不同维度的向量
|
||
每个维度查询其对应的集合
|
||
结果进行聚合
|
||
缺失的集合将被跳过(不被视为错误)
|
||
|
||
**原理:**
|
||
查询空集合是一种有效的用例
|
||
返回空结果在语义上是正确的
|
||
避免在系统启动或在数据摄取之前发生的错误
|
||
|
||
#### 4. 集合删除
|
||
|
||
**删除流程:**
|
||
```
|
||
Delete Request → List All Collections → Filter by Prefix → Delete All Matches
|
||
```
|
||
|
||
**行为:**
|
||
1. 构造前缀模式:`d_{user}_{collection}_` (注意尾随的下划线)
|
||
2. 列出向量存储中的所有集合
|
||
3. 过滤与前缀匹配的集合
|
||
4. 删除所有匹配的集合
|
||
5. 记录每个删除操作:`"Deleted collection {name}"`
|
||
6. 汇总日志:`"Deleted {count} collection(s) for {user}/{collection}"`
|
||
|
||
**示例:**
|
||
```
|
||
Collections in store:
|
||
- d_alice_papers_384
|
||
- d_alice_papers_768
|
||
- d_alice_reports_384
|
||
- d_bob_papers_384
|
||
|
||
Delete "papers" for alice:
|
||
→ Deletes: d_alice_papers_384, d_alice_papers_768
|
||
→ Keeps: d_alice_reports_384, d_bob_papers_384
|
||
```
|
||
|
||
**原理:**
|
||
确保彻底清理所有维度变体。
|
||
模式匹配可防止意外删除不相关的集合。
|
||
从用户角度来看,这是一个原子操作(所有维度一起删除)。
|
||
|
||
## 行为特性
|
||
|
||
### 正常操作
|
||
|
||
**集合创建:**
|
||
✓ 立即返回成功。
|
||
✓ 不分配任何物理存储空间。
|
||
✓ 快速操作(没有后端 I/O)。
|
||
|
||
**首次写入:**
|
||
✓ 创建具有正确维度的集合。
|
||
✓ 由于集合创建的开销,速度略慢。
|
||
✓ 之后对同一维度的写入速度很快。
|
||
|
||
**在任何写入之前进行查询:**
|
||
✓ 返回空结果。
|
||
✓ 没有错误或异常。
|
||
✓ 系统保持稳定。
|
||
|
||
**混合维度写入:**
|
||
✓ 自动为每个维度创建单独的集合。
|
||
✓ 每个维度都隔离在自己的集合中。
|
||
✓ 没有维度冲突或模式错误。
|
||
|
||
**集合删除:**
|
||
✓ 移除所有维度变体。
|
||
✓ 彻底清理。
|
||
✓ 没有孤立的集合。
|
||
|
||
### 边界情况
|
||
|
||
**多个嵌入模型:**
|
||
```
|
||
Scenario: User switches from model A (384-dim) to model B (768-dim)
|
||
Behavior:
|
||
- Both dimensions coexist in separate collections
|
||
- Old data (384-dim) remains queryable with 384-dim vectors
|
||
- New data (768-dim) queryable with 768-dim vectors
|
||
- Cross-dimension queries return results only for matching dimension
|
||
```
|
||
|
||
**并发首次写入:**
|
||
```
|
||
Scenario: Multiple processes write to same collection simultaneously
|
||
Behavior:
|
||
- Each process checks for existence before creating
|
||
- Most vector stores handle concurrent creation gracefully
|
||
- If race condition occurs, second create is typically idempotent
|
||
- Final state: Collection exists and both writes succeed
|
||
```
|
||
|
||
**维度迁移:**
|
||
```
|
||
Scenario: User wants to migrate from 384-dim to 768-dim embeddings
|
||
Behavior:
|
||
- No automatic migration
|
||
- Old collection (384-dim) persists
|
||
- New collection (768-dim) created on first new write
|
||
- Both dimensions remain accessible
|
||
- Manual deletion of old dimension collections possible
|
||
```
|
||
|
||
**空集合查询:**
|
||
```
|
||
Scenario: Query a collection that has never received data
|
||
Behavior:
|
||
- Collection doesn't exist (never created)
|
||
- Query returns empty list
|
||
- No error state
|
||
- System logs: "Collection does not exist, returning empty results"
|
||
```
|
||
|
||
## 实现说明
|
||
|
||
### 存储后端特定说明
|
||
|
||
**Qdrant:**
|
||
使用 `collection_exists()` 进行存在性检查
|
||
使用 `get_collections()` 在删除期间进行列表操作
|
||
集合创建需要 `VectorParams(size=dim, distance=Distance.COSINE)`
|
||
|
||
**Pinecone:**
|
||
使用 `has_index()` 进行存在性检查
|
||
使用 `list_indexes()` 在删除期间进行列表操作
|
||
索引创建需要等待 "ready" 状态
|
||
Serverless 规格配置为云/区域
|
||
|
||
**Milvus:**
|
||
直接类 (`DocVectors`, `EntityVectors`) 管理生命周期
|
||
内部缓存 `self.collections[(dim, user, collection)]` 用于提高性能
|
||
集合名称经过清理(仅限字母数字 + 下划线)
|
||
支持具有自动递增 ID 的模式
|
||
|
||
### 性能考虑
|
||
|
||
**首次写入延迟:**
|
||
由于集合创建而产生的额外开销
|
||
Qdrant: ~100-500 毫秒
|
||
Pinecone: ~10-30 秒 (serverless 预配置)
|
||
Milvus: ~500-2000 毫秒 (包括索引)
|
||
|
||
**查询性能:**
|
||
存在性检查会增加最小的开销 (~1-10 毫秒)
|
||
集合存在后,不会对性能产生影响
|
||
每个维度集合都独立优化
|
||
|
||
**存储开销:**
|
||
每个集合的元数据非常少
|
||
主要开销是每个维度的存储
|
||
权衡:存储空间与维度灵活性
|
||
|
||
## 未来考虑
|
||
|
||
**自动维度合并:**
|
||
可以添加后台进程来识别和合并未使用的维度变体
|
||
这将需要重新嵌入或降维
|
||
|
||
**维度发现:**
|
||
可以公开 API 来列出集合中使用的所有维度
|
||
对于管理和监控非常有用
|
||
|
||
**默认维度偏好:**
|
||
可以跟踪每个集合的 "主" 维度
|
||
用于在维度上下文不可用的情况下进行查询
|
||
|
||
**存储配额:**
|
||
可能需要每个集合的维度限制
|
||
防止维度变体的过度繁殖
|
||
|
||
## 迁移说明
|
||
|
||
**从预维度后缀系统:**
|
||
旧集合:`d_{user}_{collection}` (没有维度后缀)
|
||
新集合:`d_{user}_{collection}_{dim}` (带有维度后缀)
|
||
没有自动迁移 - 旧集合仍然可以访问
|
||
如果需要,请考虑手动迁移脚本
|
||
可以同时运行这两种命名方案
|
||
|
||
## 引用
|
||
|
||
集合管理:`docs/tech-specs/collection-management.md`
|
||
存储模式:`trustgraph-base/trustgraph/schema/services/storage.py`
|
||
Librarian 服务:`trustgraph-flow/trustgraph/librarian/service.py`
|