分布式架构概述
Milvus 旨在实现大规模向量的高效相似性搜索和分析。一个独立的 Milvus 实例可以轻松处理十亿规模向量的向量搜索。但是,对于 100 亿、1000 亿甚至更大的数据集,则需要一个 Milvus 集群。集群可作为独立实例用于上层应用,并能满足海量数据低延迟、高并发的业务需求。Milvus 集群可以重发请求、读写分离、水平扩展和动态扩展,从而提供一个可以无限制扩展的 Milvus 实例。Mishards 是 Milvus 的分布式解决方案。
本文将简要介绍 Mishards 架构的组件。更多详细信息将在接下来的文章中介绍。
1-milvus-cluster-mishards.png
分布式架构概述
2-distributed-architecture-overview.png
服务跟踪
3-service-tracing-milvus.png
主要服务组件
- 服务发现框架,如 ZooKeeper、etcd 和 Consul。
- 负载平衡器,如 Nginx、HAProxy、Ingress Controller。
- Mishards 节点:无状态、可扩展。
- 只能写入的 Milvus 节点:单节点,不可扩展。该节点需要使用高可用性解决方案,以避免单点故障。
- 只读 Milvus 节点:有状态节点,可扩展。
- 共享存储服务:所有 Milvus 节点都使用共享存储服务共享数据,如 NAS 或 NFS。
- 元数据服务:所有 Milvus 节点都使用该服务共享元数据。目前只支持 MySQL。该服务需要 MySQL 高可用性解决方案。
可扩展组件
- 数据仓库
- 只读 Milvus 节点
组件介绍
Mishards 节点
Mishards 负责分解上游请求,并将子请求路由到子服务。结果汇总后返回上游。
4-mishards-nodes.jpg
如上图所示,在接受 TopK 搜索请求后,Mishards 会首先将请求分解为子请求,然后将子请求发送给下游服务。当收集到所有子响应后,再将子响应合并并返回给上游。
由于 Mishards 是一种无状态服务,它不保存数据,也不参与复杂的计算。因此,节点对配置要求不高,计算能力主要用于合并子结果。因此,可以增加 Mishards 节点的数量,以实现高并发。
Milvus 节点
Milvus 节点负责 CRUD 相关的核心操作,所以对配置要求相对较高。首先,内存大小要足够大,避免过多的磁盘 IO 操作。其次,CPU 配置也会影响性能。随着集群规模的增加,需要更多的 Milvus 节点来提高系统吞吐量。
只读节点和可写节点
- Milvus 的核心操作符是向量插入和搜索。搜索对 CPU 和 GPU 配置的要求极高,而插入或其他操作的要求相对较低。将运行搜索的节点与运行其他操作符的节点分开,可以带来更经济的部署。
- 在服务质量方面,当一个节点执行搜索操作时,相关硬件处于满负荷运行状态,无法保证其他操作的服务质量。因此,使用了两种节点类型。搜索请求由只读节点处理,其他请求由可写节点处理。
只允许有一个可写节点
目前,Milvus 不支持多个可写实例共享数据。
在部署过程中,需要考虑可写节点的单点故障。需要为可写节点准备高可用性解决方案。
只读节点的可扩展性
当数据量极大或对延迟要求极高时,可以将只读节点作为有状态节点进行水平扩展。假设有 4 台主机,每台主机的配置如下:CPU 内核:1616、GPU1,内存:64 GB。下图显示了横向扩展有状态节点时的集群。计算能力和内存都是线性扩展。数据分为 8 个分片,每个节点处理来自 2 个分片的请求。
5-read-only-node-scalability-milvus.png
当某些分片的请求数量较大时,可以为这些分片部署无状态只读节点,以提高吞吐量。以上面的主机为例。当主机组合成无服务器集群时,计算能力会线性增加。由于需要处理的数据不会增加,因此相同数据分片的处理能力也会线性增加。
6- 只读节点可扩展性-milvus-2.png
元数据服务
关键字MySQL
有关 Milvus 元数据的更多信息,请参阅如何查看元数据。在分布式系统中,Milvus 可写节点是元数据的唯一生产者。Mishards 节点、Milvus 可写节点和 Milvus 只读节点都是元数据的消费者。目前,Milvus 只支持 MySQL 和 SQLite 作为元数据的存储后台。在分布式系统中,该服务只能部署为高可用的 MySQL。
服务发现
关键字Apache Zookeeper、etcd、Consul、Kubernetes
7-服务发现.png
服务发现提供所有 Milvus 节点的信息。Milvus 节点上线时会注册自己的信息,下线时会注销。Milvus 节点还可以通过定期检查服务的健康状态来检测异常节点。
服务发现包含很多框架,包括 etcd、Consul、ZooKeeper 等。Mishards 定义了服务发现接口,并提供了通过插件进行扩展的可能性。目前,Mishards 提供两种插件,分别对应 Kubernetes 集群和静态配置。你可以根据这些插件的实现来定制自己的服务发现。这些接口是临时的,需要重新设计。有关编写自己的插件的更多信息将在接下来的文章中详细阐述。
负载平衡和服务分片
关键字Nginx、HAProxy、Kubernetes
7-load-balancing-and-service-sharding.png
服务发现和负载均衡是一起使用的。负载平衡可配置为轮询、散列或一致散列。
负载平衡器负责将用户请求重新发送到 Mishards 节点。
每个 Mishards 节点通过服务发现中心获取所有下游 Milvus 节点的信息。所有相关的元数据都可以通过元数据服务获取。Mishards 通过消耗这些资源来实现分片。Mishards 定义了与路由策略相关的接口,并通过插件提供扩展。目前,Mishards 提供基于最低段级别的一致散列策略。如图所示,共有 10 个段,即 s1 至 s10。根据基于段的一致散列策略,Mishards 会将有关 s1、24、s6 和 s9 的请求路由到 Milvus 1 节点,将有关 s2、s3 和 s5 的请求路由到 Milvus 2 节点,将有关 s7、s8 和 s10 的请求路由到 Milvus 3 节点。
您可以根据业务需要,按照默认的一致散列路由插件定制路由。
跟踪
关键字OpenTracing、Jaeger、Zipkin
鉴于分布式系统的复杂性,请求会被发送到多个内部服务调用。为了帮助找出问题所在,我们需要跟踪内部服务调用链。随着复杂性的增加,可用跟踪系统的好处不言自明。我们选择了 CNCF OpenTracing 标准。OpenTracing 为开发人员提供了独立于平台、独立于厂商的应用程序接口,方便他们实施跟踪系统。
8-tracing-demo-milvus.png
上图是在搜索调用过程中进行跟踪的示例。搜索连续调用了get_routing
、do_search
和do_merge
。do_search
还调用了search_127.0.0.1
。
整个跟踪记录形成如下树状:
8-search-traceid-milvus.png
下图显示了每个节点的请求/响应信息和标记示例:
request-response-info-tags-node-milvus.png
Milvus 已集成 OpenTracing。更多信息将在接下来的文章中介绍。
监控和警报
关键字Prometheus、Grafana
10-monitor-alert-milvus.jpg
摘要
作为服务中间件,Mishards 集成了服务发现、路由请求、结果合并和跟踪功能。此外还提供基于插件的扩展。目前,基于 Mishards 的分布式解决方案仍存在以下不足:
- Mishards 使用代理作为中间层,存在延迟成本。
- Milvus 可写节点是单点服务。
- 依赖于高可用的 MySQL 服务。
- 缺乏缓存层,如对元数据的访问。
我们将在即将推出的版本中修复这些已知问题,以便更方便地将 Mishards 应用到生产环境中。
Like the article? Spread the word