我部署了一个RedisSearch服务器来测试向量相似度搜索。我几乎完全遵循了本指南,使用 HNSW 算法:
我的主要目标是测试中等规模数据集(约 2000 万个文档)和大量返回文档(约 5_000 到 10_000)的 RedisSearch 性能,因为一旦我们开始增加
k
和 ,用于矢量相似性搜索的 ElasticSearch 解决方案就非常慢num_candidates
返回一个大的结果集。
我们有一个嵌入模型,并且基于 ES 测试,它生成了足够的嵌入。
因此,由于我们只需要测试 Redis VSS 的性能(时间方面),为了节省使用模型生成真实嵌入的时间和金钱,我通过以下方式为每个文档生成了假嵌入:
list(np.random.rand(1024))
然后将 2000 万份文档索引到 Redis 中。因此,现在当我执行搜索并请求 1_000 个文档时,我确实会一致地返回 1_000 个文档。 但是请求 5_000 个或更多文档时,我开始得到空集或文档数量少于指定数量的集。
这部分我不明白。我在代码中没有指定我需要相似度分数高于某个特定值的文档。我只需要 5_000 或 10_000 个具有任何分数的文档。
如何让 Redis VSS 返回所需数量的具有任何相似度分数的文档?
搜索片段:
def search_redis(
redis_client: redis.Redis,
user_query: str,
index_name: str = INDEX_NAME,
vector_field: str = "embedding",
return_fields: list = ["id", "user_id", "title", "vector_score"],
hybrid_fields = "*",
k: int = 100,
):
embedded_query = get_fake_embeddings() # 1024 random floats
base_query = f'{hybrid_fields}=>[KNN {k} @{vector_field} $vector AS vector_score]'
query = (
Query(base_query)
.return_fields(*return_fields)
.sort_by("vector_score")
.paging(0, k)
.dialect(2)
)
params_dict = {"vector": np.array(embedded_query).astype(dtype=np.float32).tobytes()}
results = redis_client.ft(index_name).search(query, params_dict)
return results.docs
这可能是
TIMEOUT
和 ON_TIMEOUT
配置选项值的结果,我猜你还没有接触过。
默认情况下,
TIMEOUT
为 500 毫秒。因此,如果您的查询变长,它将在 500 毫秒后超时。够简单的。
但是,
ON_TIMEOUT
选项决定了超时时会发生什么。默认为RETURN
。因此,超时后,对 FT.SEARCH
的调用将仅返回迄今为止找到的内容。
如果您想查看这是否是问题所在,请尝试将
ON_TIMEOUT
设置为 FAIL
,看看是否会失败。如果是这样,您可以通过将 TIMEOUT
设置为 0 来禁用超时。
有关这些选项的详细信息以及如何获取和设置这些选项位于 here,但执行此操作的快速方法是使用 FT.CONFIG 命令。像这样:
redis.cloud> FT.CONFIG GET ON_TIMEOUT
1) 1) ON_TIMEOUT
2) "return"
redis.cloud> FT.CONFIG GET TIMEOUT
1) 1) TIMEOUT
2) "500"
redis.cloud> FT.CONFIG SET ON_TIMEOUT FAIL
OK
redis.cloud> FT.CONFIG SET TIMEOUT 0
OK
redis.cloud> FT.CONFIG GET ON_TIMEOUT
1) 1) ON_TIMEOUT
2) "fail"
redis.cloud> FT.CONFIG GET TIMEOUT
1) 1) TIMEOUT
2) "0"