向量数据库

向量数据库是 AI 时代新增的数据层组件,专门存储高维向量(Embedding)并提供近似最近邻搜索(ANN),是 RAG、语义检索、以图搜图的核心基础设施。

为什么需要专门的向量数据库

传统数据库(MySQL / ES):
  - 精确匹配(WHERE id = 123)
  - 关键词匹配(LIKE '%关键词%')
  - 倒排索引(全文搜索)

向量数据库:
  - 语义匹配("猫" 和 "kitten" 距离相近)
  - 跨模态匹配(文字 ↔ 图片)
  - 高维空间相似度搜索(k=10 最近邻)

核心模型

文本 / 图片 / 音频
     │
     ▼
Embedding 模型
     │  text-embedding-3-large、BGE、CLIP
     ▼
高维向量(768 / 1024 / 1536 / 3072 维浮点数组)
     │
     ▼
向量数据库
     │  存储 + 索引
     ▼
查询时:query 向量 → 找 Top-K 最相似向量

关键概念:

概念说明
Vector / Embedding高维浮点数组,表示语义
Distance Metric距离度量:Cosine(余弦)/ L2(欧式)/ Dot Product
ANN(Approximate NN)近似最近邻,牺牲精度换速度
Recall召回率,正确结果占返回结果比例
QPS每秒查询数

ANN 索引算法

精确最近邻在百万级以上数据量时不可行(O(N)),生产环境都用近似算法:

算法原理特点
HNSW分层小世界图综合最优,主流选择
IVF倒排文件 + 聚类内存占用低
IVF-PQIVF + 乘积量化极致省内存,精度略降
ScaNNGoogle 出品,量化 + 各向异性高精度高性能
LSH局部敏感哈希简单,精度较差
DiskANN磁盘索引数据量超大时使用

HNSW 简化示意:

Layer 2:    ●─────────●          稀疏层(远距离跳跃)
            │         │
Layer 1:    ●──●──●──●            中间层
            │  │  │  │
Layer 0:    ●●●●●●●●●●●●●          全节点(精细搜索)

查询:
1. 从顶层开始,找最近邻节点
2. 下沉一层,继续搜索更近的节点
3. 在最底层找到 Top-K

主流方案对比

方案语言索引特点适用场景
QdrantRustHNSW高性能、过滤强、云原生生产首选
MilvusGo+C++HNSW/IVF/DiskANN多种索引、分布式大规模(10亿+)
pgvectorC(PG 插件)IVFFlat / HNSW复用 PG 事务和 SQL中小规模、简单部署
WeaviateGoHNSWGraphQL API、模块化知识图谱
ChromaPythonHNSW嵌入式、轻量本地开发、原型
Pinecone闭源 SaaS专有全托管、零运维不想自建的团队
ElasticsearchJavaHNSW(8.x+)全文 + 向量混合已有 ES 集群
Redis StackCHNSW与 Redis 缓存复用已用 Redis

Qdrant 架构(推荐)

┌─────────────────────────────────────────┐
│           Qdrant Cluster                │
│                                         │
│   Node 0     Node 1     Node 2          │
│                                         │
│  Collection: documents                  │
│    ├── Shard 0 (Primary, Replica)       │
│    ├── Shard 1 (Primary, Replica)       │
│    └── Shard 2 (Primary, Replica)       │
│                                         │
│  Vectors + Payload(结构化元数据)       │
└─────────────────────────────────────────┘

核心特性:

  • Payload 过滤:向量 + 结构化字段联合查询(“找最相似且 user_id=123”)
  • 量化压缩:Scalar / Product / Binary Quantization,省 4~32 倍内存
  • 预过滤优化:先过滤再向量搜索,避免低效后过滤
  • MMR / Diversity:保证返回结果多样性

示例:插入和查询

from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct, Filter
 
client = QdrantClient(host="qdrant", port=6333)
 
client.create_collection(
    collection_name="docs",
    vectors_config=VectorParams(size=1536, distance=Distance.COSINE),
)
 
client.upsert(
    collection_name="docs",
    points=[
        PointStruct(
            id=1,
            vector=[0.05, 0.12, ...],
            payload={"text": "K8s 入门", "tag": "k8s"},
        ),
    ],
)
 
results = client.search(
    collection_name="docs",
    query_vector=[0.04, 0.10, ...],
    query_filter=Filter(must=[{"key": "tag", "match": {"value": "k8s"}}]),
    limit=10,
)

典型应用场景

RAG(检索增强生成)

用户提问:"K8s 怎么扩容?"
     │
     ▼
Embedding(提问 → 向量)
     │
     ▼
向量库检索 Top-10 相关文档片段
     │
     ▼
Reranker 精排(CrossEncoder / BGE-Reranker)
     │
     ▼
拼接 Prompt:[相关片段] + 用户问题
     │
     ▼
LLM 生成答案

详见 AI 云原生

语义搜索

替代传统关键词搜索:

  • 用户搜 “电动车续航差” → 也能匹配到 “EV 电池衰减” 的文章
  • 跨语言:中文 query 匹配英文文档(多语言 Embedding 模型)

以图搜图 / 图文检索

用 CLIP 模型,文本和图片映射到同一向量空间:

图片1 → CLIP image 编码 → 向量 → 入库
"一只橘猫" → CLIP text 编码 → 向量 → 检索 → 返回相似图片

推荐系统召回

用户 Embedding(基于历史行为)
     │
     ▼
向量检索 Top-200 候选商品
     │
     ▼
精排模型(CTR / LTR) → Top-20 推荐

异常检测

将用户行为编码成向量,异常请求与正常分布距离远,触发告警。

只有向量召回有时不够精准,结合关键词检索效果更好:

用户 query "K8s Pod 调度"
     │
     ├── 向量召回(语义相似)→ Top-50
     └── BM25 召回(关键词)→ Top-50
     │
     ▼
Reciprocal Rank Fusion(RRF 合并排序)
     │
     ▼
Reranker 精排 → Top-10

Qdrant、Weaviate、Elasticsearch 都已原生支持混合检索。

性能优化

优化说明
量化压缩float32 → int8 / 1bit,省 4~32 倍内存
HNSW 参数调优Mef_constructionef 三者平衡精度/速度
预过滤索引Payload 字段建索引,过滤前置
分片 + 副本横向扩容,多副本提升 QPS
冷热分层热向量内存,冷向量 SSD/磁盘(DiskANN)
异步写入批量写入,索引后台构建

K8s 部署

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: qdrant
spec:
  serviceName: qdrant
  replicas: 3
  template:
    spec:
      containers:
      - name: qdrant
        image: qdrant/qdrant:latest
        ports:
        - containerPort: 6333  # HTTP
        - containerPort: 6334  # gRPC
        volumeMounts:
        - name: storage
          mountPath: /qdrant/storage
        resources:
          requests:
            memory: "8Gi"
            cpu: "2"
          limits:
            memory: "16Gi"
            cpu: "4"
  volumeClaimTemplates:
  - metadata:
      name: storage
    spec:
      accessModes: [ReadWriteOnce]
      resources:
        requests:
          storage: 100Gi

生产建议:

  • 使用 StatefulSet(向量索引有状态)
  • 内存要充足(向量大头在内存)
  • SSD 存储(IO 密集)
  • 配合 Operator(如 Qdrant Operator)自动化运维

与 ES / 关系库的关系

维度关系库ES向量库
数据类型结构化文档 + 倒排索引高维向量
查询精确 / SQL全文 / 聚合相似度 / kNN
主键ID_idPoint ID
关联JOIN父子文档无(Payload 内嵌)
一致性ACID近实时(1s)近实时

现代架构通常是三者并存:

  • 关系库存事务数据(订单、用户)
  • ES 提供全文搜索 + 聚合分析
  • 向量库提供语义搜索 + AI 检索

注意事项

  • Embedding 模型一致性:写入和查询必须用同一个模型(否则向量空间不同)
  • 维度匹配:1536 维向量不能查 768 维空间
  • Distance 选择:用 Cosine 时向量需 L2 归一化
  • 冷启动:向量库不像 ES 有倒排索引压缩,1 亿条 1536 维约 600GB,需要量化
  • 过滤性能:复杂 Payload 过滤可能比向量搜索还慢,要建索引
  • 版本管理:换 Embedding 模型 = 整库重建,要预留迁移方案