一架梯子,一头程序猿,仰望星空!
Qdrant向量数据库教程 > 内容正文

Qdrant存储


每个集合中的数据都被划分成片段。每个片段都有独立的向量存储、有效载荷存储和索引。

片段中的数据通常不会重叠。然而,将同一点存储在不同的片段中不会导致问题,因为搜索包含去重机制。

片段包括向量存储、有效载荷存储、向量索引、有效载荷索引和id映射器,用于存储内部和外部id之间的关系。

片段可以是“可追加”的或“不可追加”的,这取决于所使用的存储和索引类型。您可以在“可追加”片段中自由地添加、删除和查询数据。而“不可追加”片段只能读取和删除数据。

集合中片段的配置可以是不同的,且彼此独立,但至少需要一个“可追加”片段。

向量存储

根据应用程序的需求,Qdrant可以使用以下其中一种数据存储选项。选择必须在搜索速度和使用RAM的大小之间进行权衡。

内存存储 - 将所有向量存储在RAM中,具有最高的速度,因为只有在持久化时才需要磁盘访问。

Memmap存储 - 在磁盘上创建与文件相关联的虚拟地址空间。Mmapped文件不直接加载到RAM中,而是使用页面缓存来访问文件内容。这种方案允许灵活使用可用内存。具有足够的RAM,它的速度几乎和内存存储一样快。

配置Memmap存储

有两种方式来配置使用memmap(也称为在磁盘上存储):

  • 在集合创建API中为向量设置on_disk选项:

仅适用于 v1.2.0 及更高版本

PUT /collections/{collection_name}

{
    "vectors": {
      "size": 768,
      "distance": "Cosine",
      "on_disk": true
    }
}

这将创建一个立即将所有向量存储在memmap存储中的集合。在Qdrant实例使用快速磁盘并且需要处理大型集合时,这是推荐的方式。

  • 设置memmap_threshold_kb选项。此选项将设置将片段转换为memmap存储的阈值。

有两种方式实现:

  1. 可以在配置文件中全局设置阈值。参数名为memmap_threshold_kb
  2. 可以在集合创建或更新期间为每个集合单独设置阈值。
PUT /collections/{collection_name}

{
    "vectors": {
      "size": 768,
      "distance": "Cosine"
    },
    "optimizers_config": {
        "memmap_threshold": 20000
    }
}

设置memmap阈值参数的经验法则很简单:

  • 如果使用场景均衡 - 将memmap阈值设置为与indexing_threshold相同(默认为20000)。在这种情况下,优化器不会进行任何额外的运行,并且将一次性优化所有阈值。
  • 如果写入负载很高,RAM很低 - 将memmap阈值设置为比indexing_threshold更低,例如10000。在这种情况下,优化器将首先将片段转换为memmap存储,然后再应用索引。

另外,您不仅可以将memmap存储用于向量,还可以将其用于HNSW索引。要启用此功能,您需要在创建集合时将hnsw_config.on_disk参数设置为true

PUT /collections/{collection_name}

{
    "vectors": {
      "size": 768,
      "distance": "Cosine"
    },
    "optimizers_config": {
        "memmap_threshold": 20000
    },
    "hnsw_config": {
        "on_disk": true
    }
}

负载(payload)存储

Qdrant 支持两种类型的负载存储:InMemory(内存存储)和 OnDisk(磁盘存储)。

InMemory 负载存储与内存向量相同的方式进行组织。负载数据在服务启动时加载到内存中,而磁盘和RocksDB仅用于持久化。这种类型的存储速度非常快,但是可能需要大量的内存空间来存储所有数据,特别是如果负载附加了大型值(如文本摘要甚至图像)。

对于大型负载值,最好使用 OnDisk 负载存储。这种类型的存储将直接将负载读写到 RocksDB,因此不需要大量的内存来存储。然而,缺点是访问延迟。如果您需要查询基于负载的条件的向量-检查存储在磁盘上的值可能需要太长时间。在这种情况下,我们建议为每个用于过滤条件的字段创建负载索引,以避免磁盘访问。一旦创建了字段索引,Qdrant 将始终将索引字段的所有值保存在内存中,而不管负载存储类型如何。

您可以通过配置文件或在创建集合时使用 collection 参数 on_disk_payload 来指定所需的负载存储类型。

版本控制

为了确保数据的完整性,Qdrant 在两个阶段进行所有数据更改。首先,数据被写入 Write-ahead-log(WAL)中,WAL 对所有操作进行排序并分配顺序编号。

一旦更改被添加到 WAL 中,即使发生断电,也不会丢失。然后,更改进入段中。每个段存储应用于其的最新版本的更改,以及每个单独点的版本。如果新更改的顺序编号小于点的当前版本,则更新器将忽略该更改。这个机制允许 Qdrant 在异常关闭的情况下安全高效地从 WAL 恢复存储。



关联主题