文档:Valkey 搜索

Valkey-Search

Valkey-Search(BSD-3-Clause 许可证),作为一个 Valkey 模块提供,是一个高性能的向量相似度搜索引擎,专为 AI 驱动的工作负载优化。它提供个位数毫秒级延迟和高 QPS,能够处理数十亿向量,召回率超过 99%。

Valkey-Search 允许用户创建索引并执行相似度搜索,同时支持复杂的过滤器。它支持使用 HNSW 进行近似最近邻 (ANN) 搜索,以及使用 K-最近邻 (KNN) 进行精确匹配。用户可以使用 Valkey HashValkey-JSON 数据类型来索引数据。

尽管 Valkey-Search 目前专注于向量搜索,但其目标是将 Valkey 扩展为一个功能齐全的搜索引擎,支持全文搜索和额外的索引选项。

Valkey-Search 的出色用例

Valkey-Search 以毫秒级延迟搜索数十亿向量的能力使其成为实时应用的理想选择,例如

  • 个性化推荐 – 根据实时用户交互提供即时、高度相关的推荐。
  • 欺诈检测与安全 – 通过超快速相似度匹配识别异常和可疑活动。
  • 对话式 AI 与聊天机器人 – 通过利用快速的基于向量的检索来提高响应准确性和相关性。
  • 图像与视频搜索 – 通过实时相似度检测实现多媒体搜索。
  • 生成式 AI 与语义搜索 – 通过高效的向量检索支持高级 AI 应用,以实现自然语言理解。

支持的命令

FT.CREATE
FT.DROPINDEX
FT.INFO
FT._LIST
FT.SEARCH

有关支持的命令、示例和配置选项的详细说明,请参阅命令参考

扩展

Valkey-Search 支持独立模式集群模式。在这两种模式下,查询处理和数据摄取都与 CPU 核心数线性扩展。对于大规模存储需求,用户可以利用集群模式实现键空间的横向扩展。

如果副本延迟可以接受,用户可以通过将客户端导向从副本读取来实现查询的横向扩展。

混合查询

Valkey-Search 支持混合查询,将向量相似度搜索与对索引字段(例如数值索引标签索引)的过滤结合起来。

标签索引

标签是文本字段,被解释为由分隔符分隔的标签列表。通常,标签是具有有限可能值的小型值集,例如颜色、书籍类型、城市名称或作者。

  • 只有已索引的字段才能用作标签过滤器。
  • TAG 字段通过分隔符进行分词,默认是逗号“,”,但可以在索引创建时配置。
  • 标签字段只能执行前缀和精确前置过滤。不支持后缀和中缀查询。
  • 默认情况下,标签不区分大小写。例如,“Blue”和“BLUE”都将作为“blue”被索引,并在混合查询中产生相同的结果。
  • 空字符串既不被索引也不被查询。
  • 在索引和查询期间,任何尾随空格都将被移除。

语法

以下是一些在名为 color 的字段上构建过滤查询的示例。

这里 {} 是语法的一部分,| 用作 OR 运算符以支持多个标签,通用语法是

@<field_name>:{<tag>}
or
@<field_name>:{<tag1> | <tag2>}
or
@<field_name>:{<tag1> | <tag2> | ...}

例如,以下查询将返回颜色为蓝色或黑色或绿色的文档。

@color:{blue | black | green}

另一个例子是,以下查询将返回包含“hello world”或“hello universe”的文档。

@color:{hello world | hello universe}

数值索引

数值索引允许过滤查询只返回介于给定起始值和结束值之间的值。

  • 支持包含和不包含的查询。
  • 对于开放式查询,可以使用 +inf-inf 来表示起始和结束范围。

例如,以下查询将返回 2021 年至 2024 年间(含两端)出版的书籍。等效的数学表达式是 2021 <= year <= 2024

"@year:[2021 2024]"

而以下查询将返回 2021 年(不含)至 2024 年(含)间出版的书籍。等效的数学表达式是 2021 < year <= 2024

"@year:[(2021 2024]"

以下查询将返回 2024 年及以前出版的书籍(含 2024 年)。等效的数学表达式是 year <= 2024

@year:[(-inf 2024]

以下查询将返回 2015 年以后出版的书籍(不含 2015 年)。等效的数学表达式是 year >= 2015

@year:[2015 +inf]

查询规划器

利用过滤表达式来过滤结果的查询称为混合查询。标签索引和数值索引的任意组合都可以形成混合查询。

  • Pre-filtering(预过滤):预过滤依赖于辅助索引(例如标签、数值)首先找到与过滤表达式匹配的结果,而不考虑向量相似度。一旦计算出过滤后的结果,就执行暴力搜索以按向量相似度排序。
  • Inline-filtering(内联过滤):内联过滤执行向量搜索算法(例如 HNSW),同时忽略不匹配过滤条件的向量。

当过滤后的搜索空间远小于原始搜索空间时,Pre-filtering 更快。当过滤后的搜索空间较大时,inline-filtering 变得更快。Valkey-Search 的查询规划器会根据提供的过滤器自动选择这两种策略之一。

监控

要检查服务器的整体搜索指标,可以使用 INFO SEARCHINFO MODULES 命令。

以下指标已添加到 INFO 命令的输出中

  • search_used_memory_human: search_used_memory_bytes 指标的人性化可读版本
  • search_used_memory_bytes: 所有索引占用的总内存字节数
  • search_number_of_indexes: 索引模式总数
  • search_number_of_attributes: 所有索引的属性总数
  • search_total_indexed_documents: 所有索引的所有键的总数
  • search_background_indexing_status (字符串) 索引过程的状态。NO_ACTIVITY 表示空闲索引。
  • search_failure_requests_count: 所有失败请求(包括语法错误)的计数
  • search_successful_requests_count: 所有成功请求的计数
  • search_hnsw_create_exceptions_count: HNSW 创建意外错误的计数
  • search_hnsw_search_exceptions_count: HNSW 搜索意外错误的计数
  • search_hnsw_remove_exceptions_count: HNSW 移除意外错误的计数
  • search_hnsw_add_exceptions_count: HNSW 添加意外错误的计数
  • search_hnsw_modify_exceptions_count: HNSW 修改意外错误的计数
  • search_modify_subscription_skipped_count: 跳过的订阅修改计数
  • search_remove_subscription_successful_count: 成功移除订阅的计数
  • search_remove_subscription_skipped_count: 跳过的订阅移除计数
  • search_remove_subscription_failure_count: 失败的订阅移除计数
  • search_add_subscription_successful_count: 成功添加订阅的计数
  • search_add_subscription_failure_count: 添加订阅失败的计数
  • search_add_subscription_skipped_count: 跳过的订阅添加过程计数
  • search_modify_subscription_failure_count: 失败的订阅修改计数
  • search_modify_subscription_successful_count: 成功订阅修改的计数

配置

静态配置

以下配置列表可以传递给 loadmodule 命令

  1. --reader-threads: (可选) 控制执行查询的线程数量。(默认值: 主机上的物理 CPU 核心数)
  2. --writer-threads: (可选) 控制处理索引变更的线程数量。(默认值: 主机上的物理 CPU 核心数)
  3. --use-coordinator: (可选) 集群模式启用器。默认值: false
  4. --hnsw-block-size: (可选) 指定 HNSW 图用于存储新向量的分配块大小。更大的块大小可以通过提高 CPU 缓存效率来改善性能,但代价是由于为未来潜在增长预分配而增加内存使用。(默认值: 10K)
  5. --log-level 控制日志详细级别。可能的值有: debug(调试), verbose(详细), notice(通知) 和 warning(警告)。(默认值: Valkey 的日志级别)

运行时配置

以下配置列表可以在运行时使用 CONFIG SET 命令修改

  1. search.hnsw-block-size:: 指定 HNSW 图用于存储新向量的分配块大小。更大的块大小可以通过提高 CPU 缓存效率来改善性能,但代价是由于为未来潜在增长预分配而增加内存使用。(默认值: 10K)