问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Milvus - 架构设计详解

创作时间:
作者:
@小白创作中心

Milvus - 架构设计详解

引用
CSDN
1.
https://blog.csdn.net/fenglingguitar/article/details/142486888

Milvus是一个专为大规模密集向量数据集设计的开源向量数据库系统,其架构建立在流行的向量搜索库之上,如Faiss、HNSW、DiskANN和SCANN。本文将深入解析Milvus的架构设计,包括其核心功能、四层架构、数据处理流程以及核心向量执行引擎Knowhere的实现原理。

Milvus的核心功能

Milvus支持多种高级功能,包括数据分片、流式数据摄取、动态模式、结合向量和标量数据的混合搜索、多向量搜索、稀疏向量搜索等。此外,Milvus的架构设计灵活,支持不同场景下的嵌入检索。为确保高性能和可扩展性,建议将Milvus部署在Kubernetes上,以实现最佳的弹性和可用性。

Milvus的架构概览

Milvus采用共享存储架构,遵循计算与存储分离的设计原则。它的架构由四层组成:接入层、协调服务、工作节点和存储层。通过这种设计,各个层在扩展或灾难恢复时可以独立运作。

1. 接入层

接入层是用户与系统交互的入口。该层由一组无状态的代理组成,负责验证客户端请求并返回搜索结果。其功能包括:

  • 代理无状态:使用Nginx、Kubernetes Ingress、NodePort和LVS等负载均衡组件提供统一服务地址。
  • 大规模并行处理(MPP)架构:代理会对中间结果进行汇总和后处理,并将最终结果返回给客户端。

2. 协调服务

协调服务是系统的“大脑”,负责将任务分配给工作节点。其任务包括集群拓扑管理、负载均衡、时间戳生成、数据管理等。协调器分为三种类型:

  • 根协调器(Root Coordinator):处理DDL和DCL请求,管理时间戳Oracle(TSO)等。
  • 查询协调器(Query Coordinator):负责查询节点的拓扑管理和负载均衡。
  • 数据协调器(Data Coordinator):管理数据节点和索引节点的拓扑结构,触发数据刷新、压缩和索引构建。

3. 工作节点

工作节点是系统的“手”和“脚”,负责执行来自代理的DML命令。由于存储和计算分离,工作节点是无状态的,因此可以灵活扩展和灾难恢复。工作节点包括:

  • 查询节点:订阅增量日志数据,运行向量和标量数据之间的混合搜索。
  • 数据节点:处理数据插入、更新等操作,将日志数据快照存储在对象存储中。
  • 索引节点:负责索引构建。

4. 存储层

存储层是系统的“骨架”,负责数据的持久性。包括以下子模块:

  • 元存储:用于存储元数据,如集合模式和消息检查点。Milvus使用etcd作为元存储,确保高可用性和强一致性。
  • 对象存储:用于存储日志快照文件、索引文件和中间查询结果。Milvus支持MinIO、AWS S3和Azure Blob作为对象存储。
  • 日志代理:负责日志的持久化和发布-订阅服务。Milvus集群使用Pulsar作为日志代理,单机版使用RocksDB。

数据处理流程

Milvus的数据处理包括数据插入、索引建立和数据查询三个关键步骤。

1. 数据插入

每个集合可以分为若干分片,每个分片对应一个虚拟通道(vChannel)。插入或删除请求根据主键的哈希值路由到不同的分片,代理会为每个请求分配时间戳,确保数据请求的顺序正确。DML请求会写入日志序列,并最终由数据节点处理并存储。

2. 索引构建

Milvus通过索引节点构建索引,每个集合分为多个分段,每个分段都有自己的索引。索引构建过程中需要加载日志快照,将其反序列化为向量数据,并进行训练后建立索引。索引构建是一个计算和内存密集型操作,常用K-means或图遍历等技术加速处理。

3. 数据查询

查询节点从对象存储中加载索引,并对指定的集合进行向量搜索。搜索请求会并发分发给所有查询节点,每个节点独立处理搜索请求,最后由代理汇总并返回最终结果。

Knowhere:核心向量执行引擎

Knowhere是Milvus的核心向量执行引擎,支持异构计算。它集成了多个向量搜索库,如Faiss、Hnswlib和Annoy,并根据硬件选择最适合的计算方式(如SIMD指令)。Knowhere支持多种性能优化,包括比特集机制(实现软删除)、二进制向量索引和SIMD指令集优化等。

Knowhere的代码结构

Knowhere中的主要计算涉及向量操作,其索引建立流程包括四个步骤:创建索引、训练数据、插入数据和建立索引。Knowhere支持多种索引类型,如IVF、HNSW、Annoy等。此外,Knowhere还支持自动选择合适的SIMD指令,以优化查询和索引构建的性能。

总结

Milvus通过其共享存储架构、无状态工作节点和多层设计,实现了大规模密集向量数据的高效处理和查询。其灵活的架构不仅支持多种向量搜索库,还能根据不同硬件环境进行优化,确保性能的最大化。通过合理利用Kubernetes进行部署,Milvus可以轻松应对各种数据量和查询场景的需求。

附录1:应用技术介绍

1. etcd

etcd是一个分布式键值存储系统,专门用于存储和共享数据,特别适合在分布式系统中作为元数据存储和服务注册使用。它通过Raft共识算法保证高可用性和强一致性,使其非常适合用于分布式系统的配置管理、服务发现、分布式锁等场景。

  • 高可用性:etcd使用Raft算法,提供分布式系统中数据的强一致性,即使在网络分区或节点故障时,也能保证数据一致。
  • 服务发现:etcd通过其键值存储,允许系统中的服务注册自己并相互发现。这对于分布式系统中的自动化扩展和动态配置非常重要。
  • 数据持久性:etcd支持数据的持久化,适合用作系统的配置存储、元数据存储等场景。它的事务支持确保了操作的原子性。

常用场景:

  • Kubernetes使用etcd作为其集群数据的存储系统。
  • 在Milvus中,etcd用于存储系统的元数据(如集合模式、消息检查点等),并且提供服务注册和健康检查。

2. MinIO

MinIO是一款高性能的对象存储系统,完全兼容Amazon S3 API,旨在处理大量非结构化数据(如图片、视频、备份文件等)。它特别擅长在私有云和本地存储环境中提供与AWS S3相似的对象存储功能。

  • 兼容性:MinIO提供与AWS S3 API兼容的接口,应用程序可以使用标准S3客户端与MinIO进行交互,无需修改代码。
  • 性能优越:MinIO针对高速对象存储进行了优化,特别是对大规模并行请求的处理能力。
  • 轻量级和可扩展性:MinIO是一个轻量级的存储解决方案,可以在较小的计算资源下运行,但它也支持水平扩展,以应对更大的存储需求。

常用场景:

  • 私有云环境中提供类似AWS S3的对象存储。
  • 用于存储非结构化数据的集群架构中,比如Milvus的对象存储层。

3. AWS S3

AWS S3(Amazon Simple Storage Service)是Amazon Web Services提供的对象存储服务,是世界上最受欢迎的云存储服务之一。S3适合存储任何规模的文件,并通过REST API提供高可用的存储解决方案。

  • 可扩展性和高可用性:AWS S3提供几乎无限的存储空间,能够自动扩展以处理海量数据。S3背后的架构可以容忍多个数据中心的故障,确保数据的高可用性。
  • 安全性和权限控制:通过提供精细的权限控制机制(如基于IAM角色的权限、存储桶策略、对象级别的权限等),S3允许对存储的对象进行严格的访问控制。
  • 按需定价:S3根据存储的数据量和API调用频率收费,按使用付费,非常适合具有弹性需求的应用场景。

常用场景:

  • 存储备份数据、媒体文件、大数据分析结果等。
  • 用于静态网站托管或内容分发网络(CDN)。
  • Milvus可以选择将对象存储部分托管在AWS S3上,进行数据的持久化和索引管理。

4. Azure Blob

Azure Blob存储是Microsoft Azure提供的对象存储服务,适用于存储大量非结构化数据。Blob是Binary Large Object的缩写,意味着Azure Blob可以存储任何类型的数据,如文档、图片、视频等。

  • 对象存储模型:Azure Blob提供三种存储模式:块Blob、追加Blob和页Blob。块Blob是最常见的存储类型,通常用于存储视频、图片和文档等数据。追加Blob则适合日志数据的存储,页Blob则用于大规模随机访问数据。
  • 全球分布和冗余:Azure Blob可以在全球多个数据中心间复制数据,支持区域冗余存储(ZRS)、本地冗余存储(LRS)和异地冗余存储(GRS)等多种冗余模式,确保数据安全和可访问性。
  • 与Azure生态系统集成:作为Microsoft Azure云的一部分,Blob存储可以无缝地与其他Azure服务集成,如虚拟机、容器、数据湖等。

常用场景:

  • 存储数据备份、大文件、日志数据等。
  • 作为大数据分析、机器学习工作流的输入数据存储。
  • Milvus可以使用Azure Blob来托管其对象存储层的数据。

5. Pulsar

Apache Pulsar是一个分布式的、原生支持多租户的消息队列和流处理平台。它具备消息的发布-订阅机制,允许消息在不同的生产者和消费者之间传递。Pulsar具有高可用性、低延迟和水平扩展能力,非常适合用于处理实时数据流。

  • 多租户架构:Pulsar设计支持多租户,这使得它能够在单个集群中支持多个独立的应用或团队,具有很好的隔离性。
  • 消息队列和流处理:Pulsar同时支持队列模式和流处理模式,用户可以根据需求选择不同的消息处理模式。
  • 持久性和高可用性:Pulsar内置了持久化存储机制,能够保证消息的持久性和高可用性。它还提供了多副本容错机制,在系统出现故障时也能保证消息数据不会丢失。

常用场景:

  • 实时消息处理,如物联网数据、金融交易日志的处理。
  • Milvus中使用Pulsar作为日志代理,确保数据流的持久性和事件通知机制。

6. RocksDB

RocksDB是一个高性能的嵌入式键值存储系统,基于LSM树结构。它由Facebook开发,用于需要高写入性能的场景,如持久化缓存、流式数据处理、区块链等。

  • LSM树存储引擎:RocksDB使用LSM(Log-Structured Merge Tree)结构,这使得它非常适合高写入密集型的工作负载。LSM树通过批量写入和合并操作优化了磁盘IO性能。
  • 持久化和快速读写:RocksDB支持持久化的键值对存储,并且能够在SSD等硬件上实现非常高的读写性能。
  • 内嵌式存储:RocksDB通常作为嵌入式数据库与应用一起运行,应用可以直接与其进行交互,而不需要通过网络协议访问外部数据库。

常用场景:

  • 高性能缓存、流处理、日志持久化。
  • 在Milvus单机版中,RocksDB作为日志代理使用,提供本地持久化服务。

附录2:MinIO实例

以下是一个MinIO安装和使用的详细步骤示例,适用于本地部署环境(Linux环境为例)。

1. 安装MinIO

a. 下载MinIO服务器二进制文件

你可以直接从MinIO官方网站下载最新版的MinIO服务器二进制文件:

wget https://dl.min.io/server/minio/release/linux-amd64/minio

b. 给二进制文件添加执行权限

下载完成后,需要给MinIO二进制文件添加执行权限:

chmod +x minio

c. 启动MinIO服务器

启动MinIO服务器时,需要指定一个目录来存储数据,例如/mnt/data目录。如果你还没有该目录,可以先创建一个:

mkdir -p /mnt/data

启动MinIO服务器:

./minio server /mnt/data

此命令将在本地启动一个MinIO服务器,并将数据存储在/mnt/data目录下。默认情况下,MinIO服务会运行在9000端口,你可以通过http://127.0.0.1:9000访问它。

启动后,你会看到类似如下的信息:

Endpoint:  http://127.0.0.1:9000  http://192.168.1.100:9000
AccessKey: YOUR-ACCESS-KEY
SecretKey: YOUR-SECRET-KEY
Region:    us-east-1
SQS ARNs:  <none>

记下这些信息中的AccessKeySecretKey,因为你稍后需要使用它们进行身份验证。

2. 访问MinIO控制台

打开浏览器,访问http://127.0.0.1:9000,你会看到MinIO的登录界面。使用刚刚在终端中显示的AccessKeySecretKey登录。

登录成功后,进入MinIO的Web控制台,你可以在这里管理存储桶和对象文件。

3. 使用mc(MinIO Client)与MinIO交互

MinIO提供了一个名为mc的客户端工具,用于与MinIO服务器进行交互。你可以使用mc进行对象存储的管理操作,如创建存储桶、上传文件等。

a. 下载mc客户端

wget https://dl.min.io/client/mc/release/linux-amd64/mc

b. 给mc文件添加执行权限

chmod +x mc

c. 配置mc客户端

在配置之前,你需要为MinIO添加一个别名。运行以下命令,指定你的MinIO服务地址、AccessKey和SecretKey:

./mc alias set myminio http://127.0.0.1:9000 YOUR-ACCESS-KEY YOUR-SECRET-KEY

这里的myminio是你为MinIO服务设置的别名。

d. 创建存储桶

你可以通过以下命令创建一个存储桶:

./mc mb myminio/mybucket

e. 上传文件到存储桶

将本地文件上传到刚刚创建的存储桶:

./mc cp /path/to/yourfile.txt myminio/mybucket

f. 列出存储桶中的对象

列出存储桶中的对象:

./mc ls myminio/mybucket

g. 下载文件

从存储桶下载文件:

./mc cp myminio/mybucket/yourfile.txt /path/to/local/directory/

4. MinIO访问策略

MinIO允许你为存储桶设置访问策略。例如,可以将存储桶设为公开访问,允许所有人读取存储桶内的文件。

a. 设置公开访问策略

将存储桶mybucket设置为公开可读:

./mc policy set public myminio/mybucket

5. 通过S3 API进行操作

MinIO是兼容S3的对象存储,因此你可以使用S3 SDK与MinIO进行交互。

a. Python示例

安装boto3(Python的S3 SDK):

pip install boto3

以下是一个简单的Python示例,用于上传文件到MinIO:

import boto3
from botocore.client import Config

# 创建S3客户端
s3 = boto3.client('s3',
                  endpoint_url='http://127.0.0.1:9000',
                  aws_access_key_id='YOUR-ACCESS-KEY',
                  aws_secret_access_key='YOUR-SECRET-KEY',
                  config=Config(signature_version='s3v4'),
                  region_name='us-east-1')

# 上传文件到存储桶
s3.upload_file('local_file.txt', 'mybucket', 'remote_file.txt')

这个例子使用了boto3连接到MinIO,上传本地文件到mybucket存储桶中。

6. 停止MinIO服务

如果你需要停止MinIO服务器,可以使用以下命令终止进程:

pkill minio
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号