MixCoord / QueryCoordV2 / QueryNodeV2 三者交互图

目标:把 Milvus 当前控制面和查询面的三个关键角色——MixCoord、QueryCoordV2、QueryNodeV2——如何协作讲清楚。


1. 为什么单独看这三者

如果说 Milvus 最关键的控制链条是什么,我会选:

  • MixCoord:控制面总入口 / 聚合容器
  • QueryCoordV2:查询资源调度器
  • QueryNodeV2:查询执行节点

这三者共同回答了两个问题:

  1. 哪些数据应该被谁服务?
  2. 这些数据如何真正被查到?

2. 先看角色定位

2.1 MixCoord:控制面顶层聚合

在当前实现中,MixCoord 聚合了:

  • RootCoord
  • DataCoord
  • QueryCoordV2
  • StreamingCoord

它更像一个控制面容器,而不是“一个新功能模块”。

它的价值

  • 统一控制面初始化和存活管理
  • 统一 metadata 依赖(etcd/TiKV/session)
  • 把多个 coordinator 组合成一个进程级服务面

2.2 QueryCoordV2:查询资源与 placement 控制器

QueryCoordV2 不做真正的向量搜索,但它决定:

  • 哪些 QueryNode 应该持有哪些 collection/segment/channel
  • replica 怎么布局
  • load/release 如何执行
  • 如何做 rebalance 和 failover

2.3 QueryNodeV2:查询执行节点

QueryNodeV2 是真正执行 search/query 的节点。它需要:

  • 接受 load segment / watch channel 等控制操作
  • 保持 growing / sealed 数据都可见
  • 用 ShardDelegator 管理每个 vchannel/shard 的执行状态

3. 最核心的交互图

                +------------------+
                |     MixCoord     |
                |------------------|
                | RootCoord        |
                | DataCoord        |
                | QueryCoordV2     |
                | StreamingCoord   |
                +---------+--------+
                          |
                          | 控制面指令 / metadata / placement
                          v
                +------------------+
                |   QueryCoordV2   |
                |------------------|
                | load/release     |
                | replica mgmt     |
                | segment/channel  |
                | balance / failover|
                +---------+--------+
                          |
                          | 下发 load / watch / sync distribution
                          v
                +------------------+
                |   QueryNodeV2    |
                |------------------|
                | ShardDelegator   |
                | SegmentManager   |
                | segcore execute  |
                +------------------+

4. MixCoord 和 QueryCoordV2 的关系

4.1 MixCoord 中实际嵌入 QueryCoordV2

internal/coordinator/mix_coord.go 里:

  • queryCoordServer *querycoordv2.Server

这说明 QueryCoordV2 并不是外部附属模块,而是当前 MixCoord 控制面里的一部分。

4.2 启动顺序说明依赖关系

mix_coord.goinitInternal() 中,大致顺序是:

  1. 启动 streaming coord
  2. 初始化并启动 rootcoord
  3. 并行初始化 dataCoord 和 queryCoord

这说明:

  • QueryCoordV2 的生命周期受 MixCoord 管理
  • RootCoord ready 是 QueryCoordV2 正常工作的前置条件之一

4.3 你该怎么理解

MixCoord 负责把“全局 metadata / coord 体系”拉起来, QueryCoordV2 则是在这个全局控制面里专门负责 query placement 的模块。


5. QueryCoordV2 和 QueryNodeV2 的关系

这是控制面到执行面的核心接口。

5.1 QueryCoordV2 对 QueryNodeV2 发什么类型的指令

典型包括:

  • LoadCollection / LoadPartitions
  • ReleaseCollection / ReleasePartitions
  • Watch / unwatch channel
  • segment distribution sync
  • rebalance / move 操作
  • replica 相关同步

5.2 QueryCoordV2 的视角是什么

QueryCoordV2 看的是“全局放置图”——

  • 哪些 node 存活
  • 哪些 collection 已 load
  • 哪些 segment 在哪个 replica / node 上
  • 哪些 channel 被哪个 QueryNode watch

它不是“数据执行者”,而是“数据服务拓扑管理者”。

5.3 QueryNodeV2 的视角是什么

QueryNodeV2 看的是“本地执行图”——

  • 我本机持有哪些 sealed segments
  • 我维护哪些 growing segments
  • 我 watch 哪些 channel
  • 每个 shard 的 tsafe 是多少
  • delete buffer 有多少
  • partition stats 怎么更新

所以:

  • QueryCoordV2 负责 global placement
  • QueryNodeV2 负责 local execution state

6. QueryNodeV2 内部的真正执行中心:ShardDelegator

6.1 为什么它是 QueryNode 的灵魂

internal/querynodev2/delegator/delegator.go 中,ShardDelegator 接口承担:

  • Search
  • Query
  • ProcessInsert
  • ProcessDelete
  • LoadGrowing
  • LoadSegments
  • SyncDistribution
  • SyncPartitionStats
  • UpdateTSafe

这说明 QueryNode 不是“持有一堆 segment 的壳”,而是由多个 ShardDelegator 组成的 shard 级执行系统。

6.2 它和 QueryCoordV2 的互动

QueryCoordV2 的 placement 决策,最终要落到 QueryNodeV2 上形成具体状态,而这个具体状态主要就体现在:

  • 哪些 shardDelegator 被创建/销毁
  • 哪些 segments 被分配给它们
  • 哪些 distribution / stats 被同步

所以你可以把 QueryCoordV2 → QueryNodeV2 看成:

global metadata placement → local shard runtime realization


7. 三者协作的几个典型场景

场景 A:LoadCollection

Client / Proxy

MixCoord 中的 QueryCoordV2 接到 load collection

查询 metadata / replica / node 状态

决定哪些 QueryNodeV2 负责哪些 segment / channel

向对应 QueryNodeV2 下发 load/watch 指令

QueryNodeV2 建立或更新 ShardDelegator

加载 sealed segment,接入 growing channel

关键点

  • MixCoord 提供全局控制面环境
  • QueryCoordV2 做放置和副本决策
  • QueryNodeV2 负责把这些决策变成真实可查询状态

场景 B:节点故障恢复

某 QueryNodeV2 故障

QueryCoordV2 感知 node 不可用

重新计算 replica / segment / channel 放置

其他 QueryNodeV2 接管 segment/channel

新的 ShardDelegator / distribution 生效

关键点

真正保证服务连续性的,不是 ANN 算法,而是这套 placement 恢复机制。

场景 C:实时查询中的 growing 数据可见

新 mutation 进入 WAL

QueryNodeV2 相关 shard 持续消费 / catch up streaming data

ShardDelegator 更新 growing state 和 tsafe

查询时 sealed + growing 一起回答

关键点

这里 QueryCoordV2 不直接参与每一条增量执行,但它负责宏观的 shard/channel 放置和 watch 拓扑。


8. 为什么 MixCoord 的存在会改变理解方式

如果没有 MixCoord,你可能会简单理解成:

  • RootCoord / DataCoord / QueryCoord 各自是独立服务

但当前实现更像:

  • 控制面在进程级被整合到 MixCoord
  • 模块之间的依赖和初始化路径更紧密
  • QueryCoordV2 是 MixCoord 内部的一部分,而不是“系统外的一层”

这会影响你读源码时的路径选择:

  • 先从 mix_coord.go 建图
  • 再分别下钻 rootcoord/datacoord/querycoordv2
  • 不要一开始就假设它们是完全分裂的外部微服务

9. 最值得追的源码路径

第一层:控制面总图

  • internal/coordinator/mix_coord.go
  • internal/distributed/mixcoord/service.go

第二层:QueryCoordV2

  • internal/querycoordv2/server.go
  • internal/querycoordv2/services.go
  • internal/querycoordv2/meta/

第三层:QueryNodeV2

  • internal/querynodev2/server.go
  • internal/querynodev2/services.go
  • internal/querynodev2/delegator/delegator.go
  • internal/querynodev2/segments/

10. 压缩总结

用最短的话讲三者关系

  • MixCoord:把控制面拉起来并统一承载 QueryCoordV2 等模块
  • QueryCoordV2:决定“谁应该服务哪些数据”
  • QueryNodeV2:把这个决策变成“这个 shard 现在真的可查”

再压缩成一句话

MixCoord 提供控制面宿主,QueryCoordV2 维护查询放置图,QueryNodeV2 通过 ShardDelegator 把放置图落实成真实的 shard 级查询执行状态。