处理更多数据,大幅降低成本!Milvus MMap 启示录

简介: 作为 VectorDBBench 中最快的开源向量数据库,Milvus 可以很好地为有高性能需求的用户服务。与此同时,我们也注意到一些用户会将 Milvus 用在离线业务中,还有部分用户对性能需求并不敏感,这意味着在同规格的实例上,他们需要以更低的成本来处理更多的数据。因此在 Milvus 2.3 中,Milvus 新增了 MMap 的功能,开启 MMap 后,能够保证相同规格的实例能够处理更大量的数据,同时对内存的大小要求会转移到磁盘上,从而大幅降低成本。在 Milvus 2.3 中,可以通过修改 milvus.yaml 来启动 MMap 功能:在 queryNode 配置项下新增

作为 VectorDBBench 中最快的开源向量数据库,Milvus 可以很好地为有高性能需求的用户服务。与此同时,我们也注意到一些用户会将 Milvus 用在离线业务中,还有部分用户对性能需求并不敏感,这意味着在同规格的实例上,他们需要以更低的成本来处理更多的数据。

因此在 Milvus 2.3 中,Milvus 新增了 MMap 的功能,开启 MMap 后,能够保证相同规格的实例能够处理更大量的数据,同时对内存的大小要求会转移到磁盘上,从而大幅降低成本。

在 Milvus 2.3 中,可以通过修改 milvus.yaml 来启动 MMap 功能:在 queryNode 配置项下新增 mmapDirPath 项,将其值设为任意合法路径即可:

接下来,让我们深入了解一下 MMap。

01.MMap 是什么?
MMap(Memory-mapped files)是一种在操作系统中实现文件和内存之间映射的技术,通过 MMap 我们可以将一个文件的内容直接映射到进程的地址空间中,使得文件的内容在内存中可以被视为一段连续的内存区域,而不必进行显式的文件读取或写入操作。MMap 提供了一种高效、方便的文件访问方式,尤其在处理大型文件或需要随机访问文件内容的情况下非常有用。

一个简单的 C 语言例子如下:

void* map = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, offset)
后续通过 map 指针读取数据时,会直接读取到 fd 所对应的文件的内容。如果读取的区域不在内存中,操作系统会将对应的 page 及相邻 page 缓存到 page cache 中,而不常访问的 page 可能会被换出。

在 Milvus 中开启 MMap 后,数据不会直接 load 到内存中,当发生查询时,数据会被动态地从磁盘加载到内存中,并且系统也会动态地将不常用的数据淘汰掉。由于 Milvus 查询集群中的数据都是 immutable 的,当数据被从内存中淘汰时,并不会发生写磁盘的操作。

  1. 性能,成本与系统的上限
    由于需要存储向量数据,向量数据库对内存容量会有较高的要求。想要在有限的内存下处理更多数据,并且对性能不是非常敏感的用户就可以通过 MMap 功能实现。系统会根据负载和使用情况从内存中淘汰掉一些数据,从而可以在相同的内存容量下处理更多数据。

寻求空间与时间的平衡点
天下没有免费的午餐,而 MMap 的代价就是性能。根据我们的测试,在内存充足时,经过 warm up 后,数据都在内存中,此时系统的性能不会有明显的降级。而当数据量不断增加,性能则会随之逐渐下降。因此我们推荐只有那些对性能不敏感的用户去使用 MMap 功能。

如大家所知,数据的访问模式会极大地影响性能。Milvus 的 MMap 功能也尽量考虑了局部性对性能的影响。对于数据部分,通常是在过滤与读取时会被访问,并且都是顺序访问,因此标量数据会被直接按顺序写入到磁盘。对于变长类型,我们做了更多的优化,如下图所示,3 个字符串分别是:

Vector

Database

Milvus

变长类型会经过扁平化,写入到连续的区域中,在内存中我们会维护一个 offsets 数组来索引数据。这样就能保证数据访问的局部性,同时也能消除单独存储每个变长数据的 overhead。

而对于向量索引,就需要更细致一些的优化了。以最常用的 HNSW 为例,HNSW 可以分为两个部分:

存储图中点之间连接关系的邻接表

原始向量数据

由于向量本身是比较大的,通常为连续的上百,或上千个 float32,因此访问单个向量本身就可以利用到局部性。而邻接表的访问模式在查询过程中则是较为随机的。向量数据通常会比邻接表要大得多,因此我们选择了只对向量数据做 MMap,而邻接表则保留在内存中,在节省大量内存的情况下保证性能不会下降太多。

Zero Copy
为了让 MMap 能够提高系统处理数据量的上限,我们首先需要保证,在整个数据加载流程中内存用量峰值一定是远低于实际数据量的。而 Milvus 在之前的版本中,QueryNode 加载数据时会将数据全量读入,数据在整个过程中会被复制。在 MMap 功能的开发过程中,我们将这一过程改为了流式的,并去掉了很多不必要的复制,大幅降低了数据加载过程中的内存开销。

经过这些优化,MMap 才能真正提升系统的能力上限,经测试,在 Milvus 2.3 中开启 MMap 后, Milvus 可以处理约 2 倍左右的数据量。

目前 MMap 功能还处于 Beta 的状态,后续我们会对整个系统的内存使用做更多优化,来实现在单个节点上支撑更大的数据量。同时也会在使用方式上做出更多迭代,支持更细粒度的控制,支持动态的更改 collection,甚至 field 的加载模式。

相关文章
|
10天前
|
JSON 缓存 自然语言处理
陈天奇团队LLM结构化生成新引擎XGrammar:百倍加速、近零开销
陈天奇团队提出XGrammar,一种新型结构化生成引擎,专注于高效生成结构化输出。XGrammar通过分类处理上下文无关和相关词汇,结合预计算、缓存及持久化执行栈,显著提升性能,实现百倍加速,令牌掩码生成时间缩短至40微秒以下。它在文本、代码生成等任务中表现出色,支持跨平台部署,尤其在JSON语法下比现有引擎快3-100倍。尽管存在分类准确性等挑战,XGrammar仍展示了广泛的应用潜力。论文:https://arxiv.org/pdf/2411.15100
35 11
|
10天前
|
存储 人工智能 监控
时序数据库 TDengine 化工新签约:存储降本一半,查询提速十倍
化工行业在数字化转型过程中面临数据接入复杂、实时性要求高、系统集成难度大等诸多挑战。福州力川数码科技有限公司科技依托深厚的行业积累,精准聚焦行业痛点,并携手 TDengine 提供高效解决方案。
22 0
|
15天前
|
存储 机器学习/深度学习 人工智能
《DeepSeek模型压缩:在高效与性能间寻平衡》
DeepSeek是人工智能领域的大语言模型佼佼者,专注于模型压缩技术。通过量化、剪枝、知识蒸馏和混合专家系统等手段,DeepSeek在减小模型体积的同时最大程度保留性能。量化将高精度参数转换为低比特数,减少存储与提升计算效率;剪枝移除冗余连接,降低计算复杂度;知识蒸馏将大模型知识传递给小模型,保持高准确率;混合专家系统按需激活模块,精准分配计算资源。这些技术使DeepSeek在智能客服、文本生成、图像识别等任务中表现出色,拓展了应用场景并提升了运行效率。
|
缓存 算法 大数据
倚天710规模化应用 - 性能优化 - 软件预取分析与优化实践
软件预取技术是编程者结合数据结构和算法知识,将访问内存的指令提前插入到程序,以此获得内存访取的最佳性能。然而,为了获取性能收益,预取数据与load加载数据,比依据指令时延调用减小cachemiss的收益更大。
|
10月前
|
存储 安全 C++
联合:节省内存利器
联合:节省内存利器
|
存储 算法 大数据
倚天性能优化--基于倚天优化后的zstd在大数据场景应用:降低存储成本+提升重IO场景性能
倚天性能优化--基于倚天优化后的zstd在大数据场景应用:降低存储成本+提升重IO场景性能
|
存储 机器学习/深度学习 人工智能
训练时间减少71.4%,存储成本节省99.9%,厦大指令调优新方案MMA让羊驼模型实现多模态
训练时间减少71.4%,存储成本节省99.9%,厦大指令调优新方案MMA让羊驼模型实现多模态
184 0
|
Cloud Native 前端开发 Serverless
《2023云原生实战案例集》——04 互联网——Wolai 使用函数计算相比传统架构节省了一半以上的费用和人力
《2023云原生实战案例集》——04 互联网——Wolai 使用函数计算相比传统架构节省了一半以上的费用和人力
|
机器学习/深度学习 Kubernetes 搜索推荐
突破百万亿参数规模,追求极致的效率和性价比:华人团队开源首个异构并行推荐系统训练框架Persia
突破百万亿参数规模,追求极致的效率和性价比:华人团队开源首个异构并行推荐系统训练框架Persia
210 0
|
存储 消息中间件 设计模式
「数据密集型系统搭建」开卷篇|什么是数据密集型系统
「数据密集型系统搭建」开卷篇|什么是数据密集型系统。系统具有数据密集型特点,底层建筑决定上层应用,数据层非常重要涉及的技术选型很多,建造者的终极之路需要突破自身界限完善能力,关注数据,抱紧业务变化。
241 0