迭代redis数据的有效方法是什么?

What is the efficient way to iterate through redis data?

你好,我有一个 Redis 数据库,其中包含 10 万多人的面部嵌入。所有这些都以键值对的形式存储在redis中。例如:

{
   "embedding:angelina" : [128-D vector of angelina],
   "embedding:emma" : [128-D vector of emma],
   "embedding:dicaprio" : [128-D vector of dicaprio]
}

现在我正在尝试将目标嵌入与数据集中的所有嵌入进行比较,以找到最佳匹配。我尝试这样做的一种方法是首先检索以 embedding* 表达式开头的所有键。然后,迭代这些嵌入并找到与目标嵌入的距离。如果距离小于阈值,那么我们将把它附加到一个列表中,然后从该列表中选择最短的距离。 我不知道,但我觉得这不是最佳做法。如果有人能帮我找到更好的方法,我会很高兴?

注意:我知道 ElasticSearch 非常适合此类任务,但我现在需要坚持使用 Redis。

可以按模式迭代 Redis 键,但这不是最佳做法。 The Redis docs 警告以下内容:

Warning: consider KEYS as a command that should only be used in production environments with extreme care. It may ruin performance when it is executed against large databases. This command is intended for debugging and special operations, such as changing your keyspace layout. Don't use KEYS in your regular application code. If you're looking for a way to find keys in a subset of your keyspace, consider using SCAN or sets.

使用SCAN可以保护Redis实例的资源,但是使用SCAN获取大数据集中的所有键仍然需要很长时间和很多请求。

根据您的情况,我想到了一些解决方法:

  1. 了解您要按的键。您可以通过以下方式做到这一点:
  • 在别处维护一个键列表,这样您就可以逐个键查找,如果您无论如何都要检查大部分键,这可能不值得麻烦。
  • 按顺序对键编号:如果您知道您将拥有 100k-200k 个键并且您不希望删除很多,您可以将键设置为“嵌入:{1-100k}”并存储值中的任何其他元数据,例如重要的 angelina
  • 在 Redis 集中维护一个键列表:这似乎是上面引用的警告中的建议。当您在数据集中添加或删除 embedding:.* 键时,还可以使用 SADDSREM 在 Set 中添加或删除键名(可以命名为例如 embedding_sample_keys) .我没试过这个,但听起来很可行。
  1. 使用散列:这会将您的所有数据存储在一个 Redis hash structure 下。 (可能关键是 embedding_data)。这有一些缺点,比如不能为每个缓存键设置不同的 TTL。您可以使用 HKEYS 和 HSCAN 访问散列中的所有键,这可能比扫描整个数据集有所改进。

这听起来很适合 Redis VSS