存储/计算分离
遵循数据平面和控制平面分离的原则,Milvus 包含四个层次,在可扩展性和灾难恢复方面相互独立。
访问层
访问层由一组无状态代理组成,是系统的前层和用户的端点。它验证客户端请求并减少返回的结果:
- Proxy 本身是无状态的。它使用负载均衡组件(如 Nginx、Kubernetes Ingress、NodePort 和 LVS)提供统一的服务地址。
- 由于 Milvus 采用大规模并行处理(MPP)架构,proxy 会聚合和后处理中间结果,然后将最终结果返回给客户端。
协调器服务
协调器服务将任务分配给工作节点,充当系统的大脑。它承担的任务包括集群拓扑管理、负载均衡、时间戳生成、数据声明和数据管理。
有三种协调器类型:root coordinator(root coord)、data coordinator(data coord)和 query coordinator(query coord)。
Root coordinator(root coord)
Root coord 处理数据定义语言(DDL)和数据控制语言(DCL)请求,如创建或删除 Collection、Partition 或索引,以及管理 TSO(时间戳预言机)和时间 ticker 发布。
Query coordinator(query coord)
Query coord 管理查询节点的拓扑和负载均衡,以及从 growing segment 到 sealed segment 的切换。
Data coordinator(data coord)
Data coord 管理数据节点和索引节点的拓扑,维护元数据,并触发 flush、compact 和索引构建等后台数据操作。
工作节点
手脚。工作节点是愚笨的执行器,遵循协调器服务的指令并执行来自 proxy 的数据操作语言(DML)命令。由于存储和计算的分离,工作节点是无状态的,并且在 Kubernetes 上部署时可以促进系统的横向扩展和灾难恢复。有三种类型的工作节点:
Query node
Query node 通过订阅日志代理检索增量日志数据并将其转换为 growing segment,从对象存储加载历史数据,并在向量和标量数据之间运行混合搜索。
Data node
Data node 通过订阅日志代理检索增量日志数据,处理变更请求,并将日志数据打包成日志快照并存储在对象存储中。
Index node
Index node 构建索引。Index node 不需要常驻内存,可以使用无服务器框架实现。
存储
存储是系统的骨架,负责数据持久化。它包括元存储、日志代理和对象存储。
元存储
元存储存储元数据的快照,如 Collection Schema 和消息消费检查点。存储元数据需要极高的可用性、强一致性和事务支持,因此 Milvus 选择 etcd 作为元存储。Milvus 还使用 etcd 进行服务注册和健康检查。
对象存储
对象存储存储日志快照文件、标量和向量数据的索引文件以及中间查询结果。Milvus 使用 MinIO 作为对象存储,可以轻松部署在 AWS S3 和 Azure Blob 上,这是世界上最受欢迎、最具成本效益的两个存储服务。但是,对象存储具有高访问延迟并按查询次数收费。为了提高性能并降低成本,Milvus 计划在基于内存或 SSD 的缓存池上实现冷热数据分离。
日志代理
日志代理是支持回放的发布-订阅系统。它负责流数据持久化和事件通知。它还确保工作节点从系统故障中恢复时增量数据的完整性。Milvus 集群使用 Pulsar 作为日志代理;Milvus 独立版使用 RocksDB 作为日志代理。此外,日志代理可以轻松替换为流数据存储平台,如 Kafka。
Milvus 围绕日志代理构建并遵循"日志即数据"原则,因此 Milvus 不维护物理表,而是通过日志持久化和快照日志确保数据可靠性。
日志代理是 Milvus 的骨干。由于其固有的发布-订阅机制,它负责数据持久化和读写分离。上图显示了该机制的简化描述,其中系统分为两个角色:日志代理(用于维护日志序列)和日志订阅者。前者记录所有改变 Collection 状态的操作;后者订阅日志序列以更新本地数据并以只读副本的形式提供服务。发布-订阅机制还为系统在变更数据捕获(CDC)和全球分布式部署方面的可扩展性留出了空间。
下一步
- 阅读主要组件了解 Milvus 架构的更多细节。