欢迎光临

Vald 云原生分布式向量搜索引擎深度解析:从架构设计到 Kubernetes 生产部署完整指南

Vald 是什么:云原生时代的向量搜索基础设施

在大模型和 RAG 应用爆发式增长的今天,向量搜索已经成为 AI 基础设施中不可或缺的一环。从 Milvus、Qdrant 到 Weaviate,市面上已有不少向量数据库方案。然而,这些方案在云原生场景下面临一个共同的痛点:它们大多以单体或伪分布式架构为主,真正与 Kubernetes 深度整合、支持自动伸缩和故障自愈的方案凤毛麟角

Vald(Vector Search Engine for Distributed Architecture)正是为解决这一痛点而生的。它是由日本 Yahoo! JAPAN 开源、目前已进入 CNCF Sandbox 的云原生分布式向量搜索引擎。Vald 从设计之初就以 Kubernetes 为一等公民,所有核心组件均以微服务形式部署,天然支持水平扩展、滚动更新和故障恢复。

Vald 的核心优势可以概括为三点:

  • 云原生架构:所有组件容器化,通过 gRPC 通信,与 Kubernetes 生态无缝集成
  • 高性能索引引擎:底层基于 Yahoo! JAPAN 研发的 NGT(Neighborhood Graph and Tree)算法,在高维向量检索中表现优异
  • 灵活的横向扩展:索引分片存储于独立 Pod,可按需增减 Agent 节点,Index Manager 自动管理分片均衡

云原生架构示意图

核心架构解析:从 Gateway 到 Agent 的全链路设计

Vald 采用典型的微服务架构,核心组件包括 Gateway、Agent、Index Manager、Backup Manager 和 Discoverer。理解这些组件的职责和交互方式,是正确部署和调优 Vald 的基础。

Gateway:统一入口与请求路由

Gateway 是 Vald 集群对外暴露的唯一入口。它接收客户端的 gRPC 请求(Insert、Search、Update、Delete 等),根据向量 ID 哈希将请求路由到对应的 Agent 节点。Gateway 本身是无状态的,可以通过增加副本数来提升吞吐量。在 Kubernetes 中,通常以 Deployment + Service 形式部署,并通过 HPA(Horizontal Pod Autoscaler)实现自动扩缩容。

Gateway 的路由策略基于一致性哈希。当 Agent 节点增减时,仅影响少量向量的路由映射,避免大规模数据迁移。这一设计使得 Vald 可以在不中断服务的情况下进行节点扩缩容。

Agent:索引存储与检索执行器

Agent 是 Vald 的核心工作节点,每个 Agent 负责存储一部分索引分片并执行向量检索。Agent 以 StatefulSet 形式部署,确保每个 Pod 拥有稳定的网络标识和持久化存储。Agent 内部运行 NGT 索引引擎,支持自动索引构建和增量更新。

Agent 的关键设计特点包括:

  • 增量索引构建:新插入的向量先写入缓冲区,达到阈值后触发后台索引构建,不影响在线检索性能
  • 自动快照:定期将索引持久化到对象存储(如 S3、MinIO),确保故障恢复时数据不丢失
  • 健康检查与自动修复:通过 Readiness/Liveness Probe 暴露索引状态,异常时由 Index Manager 触发重建

Index Manager:索引生命周期编排

Index Manager 是 Vald 的控制平面,负责索引的创建、删除、重建和分片均衡。它监听 Agent 的状态变化,当检测到节点故障或分片不均衡时,自动触发索引重建或迁移操作。Index Manager 还管理索引版本,支持滚动更新过程中的零停机切换。

Backup Manager 与 Discoverer

Backup Manager 负责将 Agent 的索引快照备份到外部存储,并在 Agent 恢复时提供数据还原。Discoverer 则是服务发现组件,基于 Kubernetes 的 Endpoints 机制动态感知 Agent 节点的上下线,并通知 Gateway 更新路由表。

分布式系统架构

NGT 索引算法:为何 Vald 的检索速度如此之快

Vald 的底层索引引擎 NGT 是其高性能的关键。NGT 是由 Yahoo! JAPAN 研发的近似最近邻搜索算法,其核心思想是通过构建邻域图(Neighborhood Graph)实现高效的向量检索。与常见的 HNSW 算法相比,NGT 在多个公开数据集上展现出更优的检索速度和召回率平衡。

NGT 的工作原理分为三个阶段:

  • 索引构建阶段:首先为所有向量构建 k-NN 图,每个节点与最近的 k 个邻居建立边。然后通过剪枝策略移除冗余边,保留高质量的导航路径
  • 搜索阶段:从随机种子点出发,沿着图的边逐步向目标向量靠近,直到无法找到更近的邻居为止。通过多点起始搜索提升召回率
  • 增量更新:新插入的向量通过搜索找到最近邻,建立边连接,并触发局部图优化以维持搜索效率

NGT 相较于 HNSW 的一个显著差异在于其动态索引优化能力。HNSW 的层级结构在建索引后基本固定,而 NGT 可以在增量更新过程中持续优化图的拓扑结构,这在频繁更新的生产场景中尤为重要。

以下是 NGT 与 HNSW 在 glove-100 数据集上的性能对比(官方基准):

算法 QPS Recall@10 索引构建时间 内存占用
NGT (Anisotropic) ~3800 0.995 中等 较高
HNSW (ef=200) ~3200 0.990 较快 中等
IVFPQ ~5500 0.850 较快 较低

可以看到,NGT 在保持接近完美召回率的同时,QPS 优于 HNSW。当然,这是以较高的内存占用为代价的——这也是 Vald 采用分布式架构的原因之一:通过 Agent 分片将内存压力分散到多个节点。

Kubernetes 生产部署实战

Vald 提供了完整的 Helm Chart,可以在 Kubernetes 集群中快速部署。以下是从零开始部署一个生产级 Vald 集群的完整步骤。

环境准备与 Helm 部署

首先确保你有一个运行中的 Kubernetes 集群(1.22+)和 Helm 3。添加 Vald 的 Helm 仓库:


1
2
3
4
5
6
7
8
9
# 添加 Vald Helm 仓库
helm repo add vald https://vald.vdaas.org/charts
helm repo update

# 查看可用的 Chart 版本
helm search repo vald/vald --versions

# 创建命名空间
kubectl create namespace vald

创建自定义的 values 文件来配置 Vald 集群:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# vald-values.yaml
gateway:
  replicas: 3
  resources:
    requests:
      cpu: "500m"
      memory: "512Mi"
    limits:
      cpu: "2000m"
      memory: "2Gi"
  hpa:
    enabled: true
    minReplicas: 3
    maxReplicas: 10
    targetCPUUtilizationPercentage: 70

agent:
  replicas: 5
  ngt:
    autoIndexDurationLimit: "30m"
    autoIndexCheckDuration: "5m"
    dimension: 768
    distance_type: "cosine"
    object_type: "float"
    creation_edge_size: 60
    search_edge_size: 30
  resources:
    requests:
      cpu: "1000m"
      memory: "4Gi"
    limits:
      cpu: "4000m"
      memory: "16Gi"
  persistence:
    enabled: true
    size: "50Gi"
    storageClass: "ssd"

index_manager:
  replicas: 1
  autoIndex: true
  autoSaveIndex: true
 
backup_manager:
  enabled: true
  storageType: "s3"
  s3:
    bucket: "vald-backup"
    region: "us-east-1"

discoverer:
  enabled: true
  discoverer:
    duration: "3s"

使用 Helm 部署 Vald:


1
2
3
4
5
6
7
helm install vald vald/vald \
  -n vald \
  -f vald-values.yaml \
  --timeout 10m

# 验证所有 Pod 已启动
kubectl get pods -n vald -w

Kubernetes 监控面板

客户端接入与数据操作

Vald 提供了多语言 SDK(Go、Java、Python、Node.js),以下以 Python SDK 为例演示基本的向量操作:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import vald
from vald.v1.vald import search_pb2, insert_pb2, object_pb2

# 创建客户端连接
channel = vald.connect("vald-gateway.vald.svc.cluster.local:8081")
stub = vald.v1.vald.vald_pb2_grpc.ValdStub(channel)

# 插入向量
vec = object_pb2.Object.Vector(id="doc-001", vector=[0.1] * 768)
insert_req = insert_pb2.Insert.Request(vector=vec)
stub.Insert(insert_req)

# 搜索向量
query = object_pb2.Object.Vector(vector=[0.12] * 768)
search_req = search_pb2.Search.Request(
    vector=query,
    config=search_pb2.Search.Config(
        num=10,           # 返回 Top-10 结果
        radius=-1.0,      # 不限制搜索半径
        epsilon=0.01,     # 搜索精度参数
        min_num=5,        # 最少返回结果数
    )
)
results = stub.Search(search_req)
for hit in results.results:
    print(f"ID: {hit.id}, Distance: {hit.distance}")

性能调优与生产最佳实践

在将 Vald 推向生产环境时,以下调优策略至关重要:

NGT 索引参数调优

NGT 的核心参数是

1
creation_edge_size

(建图时的边数)和

1
search_edge_size

(搜索时的边数)。较大的

1
creation_edge_size

会产生更精确的图,但增加索引构建时间和内存占用。一般建议:

  • 1
    creation_edge_size

    :设为 40-80 之间,维度越高取值越大

  • 1
    search_edge_size

    :设为

    1
    creation_edge_size

    的 40%-60%

  • 1
    autoIndexDurationLimit

    :设为 15-30 分钟,避免缓冲区过大影响内存

Agent 分片策略

Vald 的分片基于向量 ID 的一致性哈希。在生产环境中,建议:

  • Agent 节点数设为数据量 / 单节点内存容量的 1.2 倍(留出 20% 缓冲)
  • 使用 SSD StorageClass 作为持久化存储,避免索引加载时的 I/O 瓶颈
  • 开启 Backup Manager,设置每 6 小时自动备份索引快照

高可用与容灾

Vald 的高可用依赖 Kubernetes 的原生能力。关键配置包括:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Gateway 反亲和性,确保副本分布在不同节点
gateway:
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 100
          podAffinityTerm:
            labelSelector:
              matchLabels:
                app: vald-gateway
            topologyKey: kubernetes.io/hostname

# Agent PodDisruptionBudget
agent:
  pdb:
    enabled: true
    minAvailable: "70%"

此外,建议在 Gateway 前部署一层 Nginx Ingress 或 Envoy 作为负载均衡和 TLS 终结,并配置健康检查路由:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: vald-ingress
  namespace: vald
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
spec:
  rules:
  - host: vald-api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: vald-gateway
            port:
              number: 8081

Vald 与主流向量数据库的横向对比

在选型时,开发者需要根据具体场景权衡不同方案的优劣。以下是 Vald 与 Milvus、Qdrant 的对比:

特性 Vald Milvus Qdrant
架构模式 微服务/K8s原生 分层架构/支持K8s 单体/支持分布式
索引算法 NGT HNSW/IVF/DiskANN HNSW
增量更新 原生支持 支持(需Compaction) 原生支持
过滤搜索 有限支持 丰富支持 丰富支持
K8s集成度 极高 中等 中等
水平扩展 Agent级自动 手动/半自动 分片迁移
社区生态 CNCF Sandbox LF AI&Data 独立开源
语言生态 Go/Java/Python/Node Python/Java/Go/Node Python/Rust/Go

如果你的场景满足以下条件,Vald 是一个值得认真考虑的选择:

  • 基础架构以 Kubernetes 为核心,需要向量搜索服务与现有云原生体系深度整合
  • 向量数据规模在千万到十亿级别,需要水平扩展能力
  • 对增量更新和实时检索有较高要求
  • 团队具备一定的 Kubernetes 运维能力

反之,如果你的场景更偏向快速原型验证、需要丰富的过滤搜索能力,或者团队对 Kubernetes 不太熟悉,Milvus 或 Qdrant 可能是更务实的选择。

总结与展望

Vald 作为 CNCF 生态中唯一的云原生向量搜索引擎,在 Kubernetes 深度集成这一维度上具有不可替代的差异化优势。其 NGT 索引引擎在高召回率场景下的性能表现也十分出色。

当然,Vald 也有其局限:过滤搜索能力相对薄弱、社区规模不如 Milvus 活跃、文档和最佳实践案例仍需完善。但随着向量搜索在 AI 基础设施中的地位日益重要,以及 CNCF 生态的持续壮大,Vald 有望在云原生向量搜索这一细分赛道上占据重要一席。

对于正在构建大规模 RAG 系统或语义搜索平台的团队,建议在技术选型阶段将 Vald 纳入评估范围,特别是在 Kubernetes 环境下运行时,Vald 的部署和运维体验会是其他方案难以比拟的。

【本站文章皆为原创,未经允许不得转载】:汤不热吧 » Vald 云原生分布式向量搜索引擎深度解析:从架构设计到 Kubernetes 生产部署完整指南
分享到: 更多 (0)