Milvus 2.0 服务端 RPC 接口全解析:集合、分区、数据写入与索引构建
【免费下载链接】milvusMilvus is a high-performance, cloud-native vector database built for scalable vector ANN search项目地址: https://gitcode.com/GitHub_Trending/mi/milvus
本指南以 Milvus 2.0 时代开发者文档中的 API Reference(appendix_b_api_reference.md)为主体,系统梳理 Milvus 对外暴露的核心 RPC 服务:从集合定义(CreateCollection)、分区管理、数据写入(Insert)到索引构建(CreateIndex)的完整请求/响应消息结构。读完本文,你将掌握每个 RPC 的接口签名、参数语义、返回结构,并理解这些接口在 Proxy、RootCoord、DataCoord、IndexCoord 等组件间的实际调用链路,可直接用于协议分析、SDK 二次开发或服务端问题排查。
一、RPC 服务总览与文档背景
该文档是 Milvus 2.0 时期的服务端 API 参考,描述的是 Milvus 对外 gRPC 服务的核心接口。当时 Milvus 采用"存算分离 + 四层协调器"架构(Proxy、RootCoord、DataCoord、IndexCoord、QueryCoord),客户端 SDK 通过 gRPC 向 Proxy 发起请求,Proxy 再按请求类型转发给相应协调器。
原文档开篇给出了 22 个核心 RPC 的一览表,全部保留如下:
| RPC | 说明 |
|---|---|
| CreateCollection | 基于 schema 声明创建集合 |
| DropCollection | 删除集合 |
| HasCollection | 检查集合是否存在 |
| LoadCollection | 将集合加载进内存,供后续检索使用 |
| ReleaseCollection | 将集合从内存中释放 |
| DescribeCollection | 查看集合的 schema 及其描述性统计信息 |
| GetCollectionStatistics | 查看集合的统计信息 |
| ShowCollections | 列出所有集合 |
| CreatePartition | 创建分区 |
| DropPartition | 删除分区 |
| HasPartition | 检查分区是否存在 |
| LoadPartition | 将分区加载进内存,供后续检索使用 |
| ReleasePartitions | 将分区从内存中释放 |
| GetPartitionStatistics | 查看分区的统计信息 |
| ShowPartitions | 列出集合下的所有分区 |
| CreateIndex | 为集合中的字段创建索引 |
| DescribeIndex | 获取集合中某字段的索引详情 |
| GetIndexStates | 获取索引构建状态 |
| DropIndex | 删除集合中某字段的指定索引 |
| Insert | 向集合或分区批量插入行数据 |
| Search | 使用 ANNS 语句与布尔表达式查询集合或分区的列 |
| Flush | 将内存中的数据持久化存储 |
从当前仓库的 proto 定义看,这些 RPC 的职责划分依然清晰:DDL 类(CreateCollection、DropCollection、HasCollection、DescribeCollection、ShowCollections、CreatePartition、DropPartition、HasPartition、ShowPartitions)定义在 root_coord.proto 的RootCoordservice 中(第 23-144 行);索引类定义在 index_coord.proto 的IndexCoordservice 中(第 12-23 行)。而客户端实际调用的是MilvusService(来自外部 milvus-proto 仓库,见 how_to_develop_with_local_milvus_proto.md),Proxy 侧实现位于 internal/proxy/impl.go,例如Insert(第 2474 行)、Search(第 2869 行)、Flush(第 3707 行)。
二、公共基础结构:MsgBase 与通用响应
2.1 MsgBase:每个请求的"身份证"
MsgBase是每个请求中携带的基础结构体,用于消息队列层面的消息标识与溯源:
message MsgBase { MsgType msg_type = 1; int64 msgID = 2; uint64 timestamp = 3; int64 sourceID = 4; }- MsgType:枚举类型,用于区分消息队列中的不同消息类型,如插入消息(insert msg)、检索消息(search msg)等;
- msgID:消息的唯一标识符;
- timestamp:消息生成的时间戳;
- sourceID:消息来源的唯一标识。
在 2.0 时代的 Go 接口定义中,对应结构为commonpb.MsgBase,见 chap06_root_coordinator.md 中RootCoord接口的注释:CreateCollection、DropCollection、HasCollection、DescribeCollection等所有 DDL 请求都要求携带MsgBase,且不少接口支持"在指定时间戳查询"的语义(specified timestamp)。
2.2 Status:服务端错误码载体
几乎每个 RPC 的响应都包含common.Status。它不含 gRPC 层面的错误,而是承载服务端业务错误码:
message Status { ErrorCode error_code = 1; string reason = 2; }- error_code:枚举类型,区分执行错误的类型,完整枚举见原文档附录 D(appendix_d_error_code.md),包括
Success=0、CollectionNotExists=4、IllegalArgument=5、IllegalDimension=7、IllegalIndexType=8、IllegalCollectionName=9、IllegalTOPK=10、BuildIndexError=21、IllegalMetricType=23、IndexNotExist=25、DDRequestRace=1000等; - reason:描述详细错误的字符串。
需要说明的是:附录 D 已在当前仓库中被标注为 Deprecated(⚠️),现代版本改用merrsentinel 错误码体系(如ParameterInvalid=1100、ServiceInternal=5、FunctionFailed=2400),通过commonpb.Status.Code传递,权威定义在 pkg/util/merr/errors.go。从 root_coord.go 的CreateCollection实现可以印证这一演变:现代实现统一通过merr.Status(err)包装错误、merr.Success()表示成功。
2.3 BoolResponse:布尔查询的响应包装
对于HasCollection、HasPartition这类存在性检查接口,返回的是带 status 的布尔响应:
message BoolResponse { common.Status status = 1; bool value = 2; }value即查询结果:存在为true,不存在为false。
三、集合定义类 RPC(Definition Requests)
3.1 CreateCollection:创建集合
接口签名:
rpc CreateCollection(CreateCollectionRequest) returns (common.Status){}请求结构:
message CreateCollectionRequest { common.MsgBase base = 1; string db_name = 2; string collection_name = 3; // `schema` 是序列化后的 `schema.CollectionSchema` bytes schema = 4; }CreateCollectionRequest包含MsgBase、db_name、collection_name以及序列化的集合 schema。服务端会创建与collection_name同名的集合。值得注意:schema 以bytes序列化字节形式传输,这是早期版本的典型做法,现代版本的请求中还增加了shards_num、consistency_level、properties等字段。
CollectionSchema 结构:
message CollectionSchema { string name = 1; string description = 2; bool autoID = 3; repeated FieldSchema fields = 4; }集合 schema 包含集合的全部基础信息:
- name / description:集合名称与描述(描述由数据库管理员定义);
- autoID:决定每行数据的 ID 是否由用户自定义。为
true时系统自动为每条数据生成唯一 ID;为false时用户必须在插入时为每条实体指定 ID; - fields:
FieldSchema列表。
FieldSchema 结构:
message FieldSchema { int64 fieldID = 1; string name = 2; bool is_primary_key = 3; string description = 4; DataType data_type = 5; repeated common.KeyValuePair type_params = 6; repeated common.KeyValuePair index_params = 7; }字段 schema 包含字段的全部基础信息:
- fieldID / name / description:字段 ID、名称、描述;
- is_primary_key:是否主键;
- data_type:枚举类型,区分不同数据类型(如 FloatVector、Int64、Float 等),完整枚举见原文档末尾附录;
- type_params:data_type 的详细参数。例如向量类型需要指定维度信息,传入
<dim, 8>键值对即可让该字段存储 8 维向量; - index_params:为加速检索而构建索引时的索引详细信息。
底层实现链路:从 root_coord.go 可以看到,现代 RootCoord 收到CreateCollection后先做健康检查(merr.CheckHealthy)、记录指标(RootCoordDDLReqCounter),随后调用broadcastCreateCollectionV1落库元数据;若集合已存在且 schema 相同,则直接忽略并返回成功。整体流程如下图所示(来源:figs/root_coord_create_collection.png):
3.2 DropCollection:删除集合
接口签名:
rpc DropCollection(DropCollectionRequest) returns (common.Status) {}请求结构:
message DropCollectionRequest { common.MsgBase base = 1; string db_name = 2; string collection_name = 3; }与同名collection_name对应的集合将被删除。在现代 RootCoord 中对应 root_coord.go 的DropCollection实现。
3.3 HasCollection:检查集合是否存在
接口签名:
rpc HasCollection(HasCollectionRequest) returns (BoolResponse) {}请求结构:
message HasCollectionRequest { common.MsgBase base = 1; string db_name = 2; string collection_name = 3; }服务端通过collection_name查找集合并判断是否存在,结果通过BoolResponse.value返回。在 root_coord.proto 中该 RPC 同样定义在RootCoordservice 内。
3.4 LoadCollection:将集合加载进内存
接口签名:
rpc LoadCollection(LoadCollectionRequest) returns (common.Status) {}请求结构:
message LoadCollectionRequest { common.MsgBase base = 1; string db_name = 2; string collection_name = 3; }与同名collection_name对应的集合将被加载进内存以备检索。在现代版本中该操作已演化为异步任务式接口(Go SDK 中LoadCollection返回可Await的任务,见 client/milvusclient/collection.go),并且响应会携带加载进度信息。
3.5 ReleaseCollection:释放集合
接口签名:
rpc ReleaseCollection(ReleaseCollectionRequest) returns (common.Status) {}请求结构:
message ReleaseCollectionRequest { common.MsgBase base = 1; string db_name = 2; string collection_name = 3; }与同名collection_name对应的集合将从内存中释放,释放后无法直接检索,需重新 Load。
3.6 DescribeCollection:获取集合 schema
接口签名:
rpc DescribeCollection(DescribeCollectionRequest) returns (CollectionDescription) {}请求结构:
message DescribeCollectionRequest { common.MsgBase base = 1; string db_name = 2; string collection_name = 3; int64 collectionID = 4; }服务端通过collection_name查找集合并返回详细信息;collectionID供内部组件按 ID 获取集合详情。
响应结构:
message DescribeCollectionResponse { common.Status status = 1; schema.CollectionSchema schema = 2; int64 collectionID = 3; }schema与 CreateCollection 中的 CollectionSchema 相同。在现代 Go SDK 中,DescribeCollection会把响应解析为entity.Collection(含 ID、Schema、物理/虚拟通道、分片数、一致性级别、属性等),见 client/milvusclient/collection.go。
3.7 GetCollectionStatistics:获取集合统计信息
接口签名:
rpc GetCollectionStatistics(GetCollectionStatisticsRequest) returns (GetCollectionStatisticsResponse) {}请求结构:
message GetCollectionStatisticsRequest { common.MsgBase base = 1; string db_name = 2; string collection_name = 3; }响应结构:
message GetCollectionStatisticsResponse { common.Status status = 1; repeated common.KeyValuePair stats = 2; }stats是保存各类统计信息的键值对列表,例如可通过 key'row_count'获取集合的行数。该统计逻辑在现代由 DataCoord 提供(见 data_coord.proto 中的GetCollectionStatistics)。
3.8 ShowCollections:列出所有集合
接口签名:
rpc ShowCollections(ShowCollectionsRequest) returns (ShowCollectionsResponse) {}请求结构:无参数(早期版本)。在现代版本中增加了db_name、type、collection_names等字段以支持按库/按类型过滤。
响应结构:
message ShowCollectionsResponse { common.Status status = 1; repeated string collection_names = 2; }collection_names为包含所有集合名称的列表。Go SDK 中ListCollections即直接调用ShowCollections并读取resp.GetCollectionNames(),见 client/milvusclient/collection.go。
四、分区管理类 RPC
分区(Partition)是集合内按逻辑划分的子集,可用于按租户或业务维度隔离数据、缩小检索范围。
4.1 CreatePartition / DropPartition
接口签名:
rpc CreatePartition(CreatePartitionRequest) returns (common.Status) {} rpc DropPartition(DropPartitionRequest) returns (common.Status) {}请求结构(两者相同字段布局):
message CreatePartitionRequest { common.MsgBase base = 1; string db_name = 2; string collection_name = 3; string partition_name = 4; } message DropPartitionRequest { common.MsgBase base = 1; string db_name = 2; string collection_name = 3; string partition_name = 4; }CreatePartition在名为collection_name的集合中创建名为partition_name的分区;DropPartition删除集合中同名分区。现代 RootCoord 实现见 root_coord.go 的CreatePartition,并提供了返回 partitionID 的CreatePartitionV2变体(见 root_coord.proto)。
4.2 HasPartition:检查分区是否存在
接口签名:
rpc HasPartition(HasPartitionRequest) returns (BoolResponse) {}请求结构:
message HasPartitionRequest { common.MsgBase base = 1; string db_name = 2; string collection_name = 3; string partition_name = 4; }判断同名partition_name分区是否存在于collection_name集合中,结果由BoolResponse.value承载(存在为true)。
4.3 LoadPartitions / ReleasePartitions:批量加载与释放分区
接口签名:
rpc LoadPartitions(LoadPartitionsRequest) returns (common.Status) {} rpc ReleasePartitions(ReleasePartitionsRequest) returns (common.Status) {}请求结构(两者相同):
message LoadPartitionsRequest { common.MsgBase base = 1; string db_name = 2; string collection_name = 3; repeated string partition_names = 4; }partition_names是分区名列表;这些集合中的分区将被一次性加载进内存(Load)或从内存释放(Release)。注意原文档中 Load 版本为复数LoadPartitionsRequest,一次可加载多个分区。
4.4 GetPartitionStatistics:获取分区统计信息
接口签名:
rpc GetPartitionStatistics(GetPartitionStatisticsRequest) returns (GetPartitionStatisticsResponse) {}请求结构:
message GetPartitionStatisticsRequest { common.MsgBase base = 1; string db_name = 2; string collection_name = 3; string partition_name = 4; }服务端通过partition_name在collection_name集合中定位分区并返回其统计信息。响应结构与集合统计一致,stats同样是键值对列表,可通过'row_count'获取分区行数:
message GetPartitionStatisticsResponse { common.Status status = 1; repeated common.KeyValuePair stats = 2; }4.5 ShowPartitions:列出集合下所有分区
接口签名:
rpc ShowPartitions(ShowPartitionsRequest) returns (StringListResponse) {}请求结构:
message ShowPartitionsRequest { common.MsgBase base = 1; string db_name = 2; string collection_name = 3; int64 collectionID = 4; }响应结构:
message ShowPartitionsResponse { common.Status status = 1; repeated string partition_names = 2; repeated int64 partitionIDs = 3; }- partition_names:所有分区的名称列表;
- partitionIDs:所有分区的 ID 列表,与partition_names按下标一一对应。
五、数据写入类 RPC(Manipulation Requests)
5.1 Insert:批量插入数据
接口签名:
rpc Insert(InsertRequest) returns (InsertResponse){}请求结构:
message InsertRequest { common.MsgBase base = 1; string db_name = 2; string collection_name = 3; string partition_name = 4; repeated common.Blob row_data = 5; repeated uint32 hash_keys = 6; } message Blob { bytes value = 1; }将一批row_data(每条为Blob,即字节值)插入到collection_name集合的partition_name分区中;hash_keys用于数据分片路由(hash 到不同分片)。
响应结构:
message InsertResponse { common.Status status = 1; int64 rowID_begin = 2; int64 rowID_end = 3; }rowID_begin与rowID_end是本次插入数据分配到的 ID 区间,SDK 可据此确认数据已成功分配主键。现代版本的InsertResponse已扩展为MutationResult(含IDs、timestamp、succ_index等),对应实现见 internal/proxy/impl.go 的Proxy.Insert。
5.2 Delete:按 ID 删除
原文档中 Delete 部分仅列出DeleteByID一个入口,未展开消息定义。在现代 Milvus 中删除请求已演进为支持过滤表达式(DeleteRequest携带expr字段),由 Proxy 处理后写入消息流,最终由 DataNode 在 L0 段或删除日志中落地。
六、索引构建类 RPC(Index)
索引用于加速向量近似检索(ANNS)。以下四个 RPC 构成索引的完整生命周期:创建 → 查看详情 → 查询构建状态 → 删除。索引类型与参数的详细说明见原文档第 2.2.3 章对应的 chap03_index_service.md。
6.1 CreateIndex:创建索引
接口签名:
rpc CreateIndex(CreateIndexRequest) returns (common.Status){}请求结构:
message CreateIndexRequest { common.MsgBase base = 1; string db_name = 2; string collection_name = 3; string field_name = 4; repeated common.KeyValuePair extra_params = 5; }为collection_name集合中名为field_name的字段创建索引。extra_params用于指定索引详细信息(索引类型、metric type、nlist 等)。
底层实现链路:从 internal/proxy/impl.go 的Proxy.CreateIndex到 IndexCoord 的CreateIndex(见 index_coord.proto),最终由 DataCoord 调度索引构建任务。现代IndexCoord.CreateIndexRequest已改用collectionID/fieldID定位字段,并携带type_params、index_params、index_name、is_auto_index等字段(见 index_coord.proto)。完整调用流程如下图所示(来源:figs/root_coord_create_index.png):
6.2 DescribeIndex:获取索引详情
接口签名:
rpc DescribeIndex(DescribeIndexRequest) returns (common.Status){}请求结构:
message DescribeIndexRequest { common.MsgBase base = 1; string db_name = 2; string collection_name = 3; string field_name = 4; string index_name = 5; }获取collection_name集合中field_name字段的索引详情。index_name语义:一个字段可创建多个索引,可通过 index_name 指定具体索引。
响应结构:
message DescribeIndexResponse { common.Status status = 1; repeated IndexDescription index_descriptions = 2; } message IndexDescription { string index_name = 1; int64 indexID = 2; repeated common.KeyValuePair params = 3; }index_descriptions为索引描述列表:若请求中指定了 index_name,列表长度将为 0(按原文档语义应为返回该索引的描述);若 index_name 为空,则返回集合字段上的全部索引。params为索引详细参数。
在现代实现中该接口由 IndexCoord 提供(见 index_coord.proto),响应DescribeIndexResponse携带完整的IndexInfo(含indexed_rows、total_rows、state、index_state_fail_reason等索引构建进度与状态信息)。
6.3 GetIndexStates:获取索引构建状态
接口签名:
rpc GetIndexStates(GetIndexStatesRequest) returns (GetIndexStatesRequest){}注:原文档此处返回值类型误写为请求类型,实际应为
GetIndexStatesResponse。
请求结构:
message GetIndexStatesRequest { common.MsgBase base = 1; string db_name = 2; string collection_name = 3; string field_name = 4; string index_name = 5; }获取collection_name集合中field_name字段的索引构建进度信息。index_name用于指定要查询状态的索引。
响应结构:
message GetIndexStatesResponse { common.Status status = 1; common.IndexState state = 2; } enum IndexState { IndexStateNone = 0; Unissued = 1; InProgress = 2; Finished = 3; Failed = 4; Deleted = 5; }index state是区分索引构建不同阶段的枚举:
IndexStateNone:无状态(默认值);Unissued:任务尚未下发;InProgress:构建中;Finished:构建完成;Failed:构建失败;Deleted:索引已删除。
在现代 IndexCoord 中,该能力由GetIndexState(已标记 Deprecated,见 index_coord.proto)演变为DescribeIndex返回的IndexInfo.state字段,状态枚举同样定义于common.IndexState。
6.4 DropIndex:删除索引
接口签名:
rpc DropIndex(DropIndexRequest) returns (common.Status){}请求结构:
message DropIndexRequest { common.MsgBase base = 1; string db_name = 2; string collection_name = 3; string field_name = 4; string index_name = 5; }删除collection_name集合中field_name字段的指定索引。index_name用于指定删除哪个索引(一个字段可建多个索引)。现代 IndexCoord 的DropIndex定义见 index_coord.proto,请求结构已改为collectionID + index_name + drop_all定位索引。
七、从源码看 RPC 的落地与演变
原文档是 2.0 时代的接口快照,结合当前仓库源码可以更完整地理解这些 RPC 的职责边界与现代演变:
职责划分保持稳定:DDL 与分区管理由 RootCoord 承接,索引生命周期由 IndexCoord 承接,写入与检索由 Proxy 承接。可在 root_coord.proto 与 index_coord.proto 中逐一核对。
定位字段从名称转向 ID:现代内部 proto 大量使用
collectionID、fieldID、segmentID替代名称定位(如 index_coord.proto 的DescribeIndexRequest),减少跨组件解析开销、避免重名歧义。同步接口向异步任务演进:LoadCollection、CreateIndex 在现代版本中普遍返回异步任务(Go SDK 中通过
task.Await(ctx)等待完成,见 client/milvusclient/collection.go),并携带进度信息(如IndexInfo.indexed_rows/total_rows)。错误处理统一收敛:2.0 的
ErrorCode枚举已被merrsentinel 体系取代,RPC 返回统一通过commonpb.Status.Code + Reason表达业务错误(见 pkg/util/merr/errors.go)。协议定义外置:对外
MilvusService的 proto 定义位于独立的 milvus-proto 仓库,通过go.mod引入(github.com/milvus-io/milvus-proto/go-api/v3)。本地调试或新增 API 时可参考 how_to_develop_with_local_milvus_proto.md 使用go mod edit -replace指向本地 proto 仓库。
八、结语
本文完整继承了 Milvus 2.0 API Reference 中 22 个核心 RPC 的接口签名、请求/响应消息结构与字段语义,并结合当前仓库的 pkg/proto 定义、internal/rootcoord/root_coord.go、internal/proxy/impl.go 与 client/milvusclient 的现代实现,勾勒出这些接口从 2.0 到现代的演进脉络。对于需要做协议层开发、SDK 移植或排查 DDL/索引构建问题的开发者,这张接口地图可以作为快速定位的起点;更深入的系统架构背景可继续阅读同目录下的 chap01_system_overview.md、chap06_root_coordinator.md 与 chap03_index_service.md。
【免费下载链接】milvusMilvus is a high-performance, cloud-native vector database built for scalable vector ANN search项目地址: https://gitcode.com/GitHub_Trending/mi/milvus
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考