• 文章
  • 优化批量上传时的内存使用
返回向量搜索手册

优化批量上传时的内存使用

Sabrina Aquino

·

2025 年 2 月 13 日

Optimizing Memory for Bulk Uploads

优化批量上传期间的内存消耗

在处理大规模向量数据时,高效的内存管理始终是一个挑战。在高吞吐量数据摄取场景中,即使看似微小的配置选择也可能显著影响系统的稳定性和性能。

本文将探讨最佳实践和建议,帮助您优化 Qdrant 批量上传期间的内存使用。我们将介绍密集向量稀疏向量的场景,帮助您的部署在高负载下保持高性能,并避免内存不足错误。

密集向量与稀疏向量的索引

密集向量

Qdrant 使用基于 HNSW 的索引来对密集向量进行快速相似度搜索。默认情况下,一旦段中未索引向量的数量超过设定的 indexing_threshold,就会构建或更新 HNSW。虽然它提供了出色的查询速度,但如果 HNSW 图频繁构建或跨许多小段构建,则可能消耗大量资源

稀疏向量

稀疏向量使用倒排索引。此索引在插入更新时更新,这意味着对于稀疏向量,您无法禁用或延迟它。在大多数情况下,其开销小于构建 HNSW 图的开销,但您仍应注意每次插入更新都会触发稀疏索引更新。

密集向量的批量上传配置

执行高吞吐量向量摄取时,您有两个主要选项来处理索引开销。您应该根据您的具体工作负载和内存限制选择其中一个

  • 禁用 HNSW 索引

为了在批量摄取期间减少内存和 CPU 压力,您可以通过设置 "m": 0完全禁用 HNSW 索引。对于密集向量,m 参数定义了 HNSW 图中每个节点可以拥有的边数。这样,将不会构建密集向量索引,从而避免在摄取期间不必要的 CPU 使用。

图 1:三个关键 HNSW 参数的描述。

PATCH /collections/your_collection
{
  "hnsw_config": {
    "m": 0
  }
}

摄取完成后,您可以通过将 m 设置回生产值(通常为 16 或 32)来重新启用 HNSW。请记住,在索引构建完成之前,搜索不会使用 HNSW,因此在此期间搜索性能可能会较慢。

  • 完全禁用优化

indexing_threshold 告诉 Qdrant 在构建 HNSW 图之前,一个段中可以累积多少个未索引的密集向量。将 "indexing_threshold"=0 会完全延迟索引,使摄取速度达到最大。但是,这意味着上传的向量在上传期间不会移动到磁盘,这可能导致高 RAM 使用率

PATCH /collections/your_collection
{
  "optimizer_config": {
    "indexing_threshold": 0
  }
}

批量摄取后,将 indexing_threshold 设置为正值,以确保向量通过 HNSW 进行索引和搜索。在执行索引之前,向量将无法通过 HNSW 进行搜索。

较小的阈值(例如 100)意味着更频繁的索引,如果存在许多段,这仍然可能开销很大。较大的阈值(例如 10000)会延迟索引,以便一次批量处理更多向量,在构建索引时可能会占用更多 RAM,但总的构建次数会减少。

在这两种方法中,我们通常建议在批量摄取期间禁用 HNSW (`"m"=0`),以保持内存使用可预测。使用 indexing_threshold=0 可以作为替代方案,但前提是您的系统有足够的内存来容纳 RAM 中的未索引向量。


Qdrant 中的磁盘存储

默认情况下,Qdrant 将向量载荷数据索引保存在内存中,以确保低延迟查询。然而,在大规模或内存受限的场景中,您可以配置将其中部分或全部数据存储在磁盘上。这有助于降低 RAM 使用,但可能会增加查询延迟,特别是对于冷读取。

何时使用磁盘存储:

  • 您有非常大很少使用的载荷数据或索引,并且释放 RAM 值得承担潜在的 I/O 开销。
  • 您的数据集无法舒适地容纳在可用内存中。
  • 您想减轻内存压力。
  • 如果可以确保系统在高负载下保持稳定,您可以容忍较慢的查询。

内存映射存储和分段

Qdrant 使用内存映射文件(段)将数据存储在磁盘上。Qdrant 不会将所有向量加载到 RAM 中,而是将每个段映射到其地址空间,按需将数据分页进出。这有助于降低活动 RAM 占用空间,因为在内存压力高时可以将数据分页出去。但每个段仍然会产生开销(元数据、页表条目等)。

高吞吐量摄取期间,您可能会累积数十个小段。Qdrant 的优化器稍后可以将这些小段合并成更少、更大的段,从而减少每个段的开销并降低总内存使用量。

当您使用 "on_disk": true 创建集合时,Qdrant 将从一开始就将新插入的向量存储在内存映射存储中。例如

PATCH /collections/your_collection
{
    "vectors": {
      "on_disk": true
    }
}

这种方法立即将所有传入向量放在磁盘上,这在批量摄取的情况下效率很高。

然而,向量数据和索引是分开存储的,因此为向量启用 on_disk 不会自动将其索引存储在磁盘上。为了完全优化内存使用,您可能需要独立配置向量存储和索引存储

对于密集向量,您可以为向量数据HNSW 索引启用磁盘存储

PATCH /collections/your_collection
{
    "vectors": {
        "on_disk": true
    },
    "hnsw_config": {
        "on_disk": true
    }
}

对于稀疏向量,您需要分别对向量数据和稀疏索引启用 on_disk

PATCH /collections/your_collection
{
    "sparse_vectors": {
        "text": {
            "on_disk": true,
            "index": {
                "on_disk": true
            }
        }
    }
}

高吞吐量向量摄取的最佳实践

批量摄取可能导致高内存消耗,甚至内存不足 (OOM) 错误。如果您的当前设置出现内存不足错误,临时向上扩展(增加可用 RAM)将提供缓冲,同时您可以调整 Qdrant 的配置以实现更高效的数据摄取。

这里的关键是控制索引开销。让我们来看看在内存受限环境中进行高吞吐量向量摄取的最佳实践。

1. 立即将向量数据存储在磁盘上

减少内存使用最有效的方法是使用 on_disk: true 从一开始就将向量数据存储在磁盘上。这可以防止 RAM 在优化生效前被原始向量过载。

PATCH /collections/your_collection
{
  "vectors": {
    "on_disk": true
  }
}

以前,向量数据必须保存在 RAM 中,直到优化器将其移动到磁盘,这导致了显著的内存压力。现在,通过直接将向量写入磁盘,内存开销显著降低,使得批量摄取更加高效。

2. 禁用密集向量的 HNSW (`m=0`)

初次批量加载期间,您可以通过设置 "m": 0禁用密集索引。这确保 Qdrant 不会为传入向量构建 HNSW 图,从而避免不必要的内存和 CPU 使用。

PATCH /collections/your_collection
{
  "hnsw_config": {
    "m": 0
  },
  "optimizer_config": {
    "indexing_threshold": 10000
  }
}

3. 在批量上传之后运行优化器

Qdrant 的优化器会持续重构数据以提高搜索效率。然而,在批量上传期间,这可能导致过多的数据移动和开销,因为在新数据仍在到达的同时,段不断地被重组。

为避免这种情况,请先上传所有数据,然后让优化器一次性处理所有内容。这最大限度地减少了冗余操作,并确保了更有效的段结构。

4. 等待索引完成以释放内存

在执行其他操作之前,请等待 Qdrant 完成所有正在进行的索引任务。大型索引作业可能会使内存使用率保持较高水平,直到完全完成。

监控 Qdrant 日志或指标以确认索引何时完成——一旦完成,随着中间数据结构的释放,内存消耗应该会下降。

5. 摄取后重新启用 HNSW

摄取阶段完成后,且内存使用稳定后,通过将 m 设置回生产值(通常为 1632)来重新启用密集向量的 HNSW

PATCH /collections/your_collection
{
  "hnsw_config": {
    "m": 16
  }
}

5. 启用量化

如果您曾计划将所有密集向量存储在磁盘上,请注意,在内存压力高时,由于频繁的磁盘 I/O,搜索速度可能会急剧下降。一个更平衡的方法是标量量化:压缩向量(例如,到 int8),以便它们可以放入 RAM 中,而不会占用像完整的浮点值那样多的空间。

PATCH /collections/your_collection
{
  "quantization_config": {
    "scalar": {
      "type": "int8",
      "always_ram": true
    }
  }
}

量化向量保持在内存中,但占用空间较少,保留了基于 RAM 的搜索的大部分性能优势。了解更多关于向量量化的信息。

结论

高吞吐量向量摄取可能对 Qdrant 施加显著的内存需求,特别是当密集向量实时索引时。通过遵循这些技巧,您可以大大降低内存不足错误的风险,并在内存受限的环境中保持稳定的性能。

一如既往,监控您的系统行为。检查日志,查看指标,并密切关注内存使用情况。每个工作负载都不同,因此根据您的硬件和数据规模微调 Qdrant 的参数是明智的。

此页面有帮助吗?

感谢您的反馈!🙏

很抱歉听到您这么说。😔 您可以在 GitHub 上编辑此页面,或创建一个 GitHub 问题。