Milvus 向量数据库内存使用相关了解

发布于:2025-08-07 ⋅ 阅读:(12) ⋅ 点赞:(0)

1、支持 MMap 的数据存储

在 Milvus 中,内存映射文件允许将文件内容直接映射到内存中。这一功能提高了内存效率,尤其是在可用内存稀缺但完全加载数据不可行的情况下。这种优化机制可以增加数据容量,同时在一定限度内确保性能;但当数据量超出内存太多时,搜索和查询性能可能会严重下降,因此请根据情况选择打开或关闭此功能。

配置内存映射:从 Milvus 2.4 开始,您可以灵活调整静态配置文件,在部署前为整个集群配置默认内存映射设置。此外,您还可以动态更改参数,以微调群集和索引级别的内存映射设置。展望未来,未来的更新将把内存映射功能扩展到字段级配置。

...
queryNode:
  mmap:
    # Set memory mapping property for whole cluster
    mmapEnabled: false | true
    # Set memory-mapped directory path, if you leave mmapDirPath unspecified, the memory-mapped files will be stored in {localStorage.path}/ mmap by default. 
    mmapDirPath: any/valid/path 
....

自 2.4.10 之后,配置queryNode.mmap.mmapEnabled 分成以下四个独立字段,所有默认值均为false :

  • queryNode.mmap.vectorField, 控制向量数据是否为 mmap;

  • queryNode.mmap.vectorIndex控制向量索引是否为 mmap;

  • queryNode.mmap.scalarField控制标量数据是否为 mmap;

  • queryNode.mmap.scalarIndex控制标量索引是否为 mmap;

...
queryNode:
  mmap:
    vectorField: false # Enable mmap for loading vector data
    vectorIndex: false # Enable mmap for loading vector index
    scalarField: false # Enable mmap for loading scalar data
    scalarIndex: false # Enable mmap for loading scalar index
....

此外,只能单独为某个 Collections 打开或关闭向量索引和向量数据 mmap,而不能为其他 Collections 打开或关闭。

兼容性:如果原始配置queryNode.mmap.mmapEnabled 设置为true ,则此时新添加的配置将设置为true 。如果queryNode.mmap.mmapEnabled 设置为false ,如果新配置设置为true ,则最终值将为true

2、群集操作符期间:动态配置

在群集运行期间,可以在 Collections 或索引级别动态调整内存映射设置。

Collections 层级,内存映射会应用到集合内所有未索引的原始数据,不包括主键、时间戳和行 ID。这种方法特别适用于大型数据集的综合管理。

若要动态调整 Collections 中的内存映射设置,可使用set_properties() 方法。在这里,可以根据需要在True 或False 之间切换mmap.enabled 。

collection = Collection("test_collection") # Replace with your collection name

collection.set_properties({'mmap.enabled': True})

在 2.4.10 之后,可以使用add_field 方法调整 Collections 中的内存映射设置。在这里,可以根据需要在True 或False 之间切换mmap_enabled 

schema = MilvusClient.create_schema()

schema.add_field(field_name="embedding", datatype=DataType.FLOAT_VECTOR, dim=768, mmap_enabled=True)

对于索引级设置,内存映射可专门应用于向量索引,而不会影响其他数据类型。对于需要优化向量搜索性能的 Collections 来说,这一功能非常宝贵。

要为 Collections 中的某个索引启用或禁用内存映射,可调用alter_index() 方法,在index_name 中指定目标索引名称,并将mmap.enabled 设置为True 或False

collection.alter_index(
    index_name="vector_index", # Replace with your vector index name
    extra_params={"mmap.enabled": True} # Enable memory mapping for index
)

3、建议在哪些情况下启用内存映射?启用此功能后有哪些权衡?

内存有限或性能要求适中时,建议使用内存映射。启用此功能可提高数据加载能力。例如,在 2 个 CPU 和 8 GB 内存的配置下,启用内存映射比不启用内存映射加载的数据多 4 倍。对性能的影响各不相同:

  • 在内存充足的情况下,预期性能与只使用内存的情况类似。

  • 如果内存不足,预期性能可能会下降。

  • Collection-level 和 Index-level 配置之间的关系是什么?

    Collection-level 和 index-level 不是包含关系,Collection-level 控制原始数据是否启用了 mmap,而 index-level 仅适用于向量索引。

  • 有没有推荐用于内存映射的索引类型?

    有,建议使用 HNSW 启用毫米映射。我们曾测试过 HNSW、IVF_FLAT、IVF_PQ/SQ 系列索引,IVF 系列索引的性能下降严重,而 HNSW 索引启用毫米映射后的性能下降仍在预期之内。

  • 内存映射需要什么样的本地存储?

    高质量的磁盘可以提高性能,NVMe 驱动器是首选。

  • 标量数据能否进行内存映射?

    内存映射可应用于标量数据,但不适用于基于标量字段建立的索引。

  • 如何确定不同级别内存映射配置的优先级?

    在 Milvus 中,当跨多个级别明确定义内存映射配置时,索引级和 Collect 级配置共享最高优先级,然后是集群级配置。

  • 如果我从 Milvus 2.3 升级,并配置了内存映射目录路径,会发生什么情况?

    如果从 Milvus 2.3 升级并配置了内存映射目录路径 (mmapDirPath),您的配置将被保留,启用内存映射的默认设置 (mmapEnabled) 将是true 。迁移元数据对同步现有内存映射文件的配置很重要。

4、Milvus为什么需要load整个index data到内存中,而不是类似MySQL这种传统数据库做分片加载

向量每个维度的值是float32,占用4个字节。每条1536维的向量占用的空间是6KB。1000条就是6MB,一百万条6GB,一亿条就是600GB,十亿条就是6TB。这个是理论值。然后用不同的索引类型使用的内存关系如下:HNSW/IVF_FLAT ------------- 这两种需要的内存和理论值基本相等IVF_SQ8/IVF_PQ-------------- 这两种需要的内存大约相当于理论值的25%~30%

如果除了向量之外还有别的字段,比如Int64类型的字段,十亿条就占用 十亿乘以8字节 这么多空间。如果是VARCHAR类型,那就跟字符串的长度相关,由于是用UTF-8编码,每个字符可能占用1~4字节。

所以,你基本可以按这个路子估计出任意数据所需的最小内存。

选择占内存小的索引是最简单的方法。降维也是一个方法,但降维的工具你要自己去找。

  1. 换索引类型

  1. 降维HNSW/IVF_FLAT更适用于高维向量且对内存和查询速度有较高要求,而IVF_SQ8/IVF_PQ适用于大规模数据且能够在较低的内存消耗下实现高效的近似最近邻搜索。不知道这个对索引选用的说法对不对。像我这个大规模数据,感觉是得用IVF_SQ8/IVF_PQ去搞

IVF_SQ8对搜索精度有较大影响DiskANN需要高性能磁盘,并且对延迟有很大影响HNSW需要较多的内存使用你也可以直接使用Zilliz cloud的Capacity optimized 实例,目前是性价比比较高的选择。1亿向量大概只需要16CU,大概一万多一个月


网站公告

今日签到

点亮在社区的每一天
去签到