在Redis中有效地缓存搜索结果

4
我需要一种在我的 node.js 应用程序中缓存搜索的方法。我有一个使用 redis 的想法,但是我不确定如何实现它。
我想要做的是在缓存中设置一个硬限制,因为我的 RAM 有限。对于每个搜索,我想要存储搜索查询和相应的搜索结果。
假设我缓存的搜索数量的硬限制是 4。下面是一个示意图,其中每个搜索查询都是一个方块:
如果有一个新的搜索没有被缓存,那么这个新的搜索就会被推到顶部,底部的搜索查询将被删除。
但是,如果有一个已经被缓存的搜索,缓存的搜索查询就会从原来的位置删除,并添加到缓存的顶部。例如,如果搜索了 "search 3"。
通过这样做,我可以使用相对同样数量的内存,而最常搜索的查询总是在缓存中浮动,不太受欢迎的搜索会经过缓存并被删除。
我的问题是,我该怎么做呢?我认为可能可以使用列表来解决,但是我不确定如何检查列表中是否存在某个值。我还认为可能可以使用排序集来解决,其中我将设置集合的分数为索引,但是如果搜索查询在缓存中移动,我需要更改集合中每个元素的分数。
3个回答

4
最简单的方法是为处理搜索缓存而启动一个新的redis实例。对于该实例,您可以根据需要设置最大内存。然后,您将为该实例设置maxmemory-policyallkeys-lru。通过这样做,redis将自动删除最近最少使用的缓存条目(这就是您想要的)。此外,您将限制实际上是通过内存使用而不是通过最大缓存条目数。
然后,您将向此redis实例插入键:search:$seachterm => $cachedvalue并为此键设置几分钟的过期时间(以避免提供陈旧的答案)。通过这样做,redis将为您完成艰苦的工作。

我认为这比其他答案和我即将建议的更容易。我还建议添加在键上使用expires命令。您可以将其缓存10秒钟。 - jdi
当然,我忘了。这样你就不会提供陈旧的响应了。 - anydot

2

您一定想使用sortedset

以下是操作步骤:

第1个查询:从排序集中选择顶部元素:zrevrange (0,1) WITHSCORES

第2个查询:在multi中执行以下操作: A. 使用检索到的分数插入元素+ 1。如果该元素已存在于列表中,则仅对其进行重新评分,而不会再次添加。

B. zremrankbyrank。我没有测试过,但我认为您要使用的参数是(0,-maxListSize)


我认为“绝对”可能是一个太严格的陈述。这显然是一种方法,但我认为在客户端必须完全管理集合会更加复杂。它也没有解决内存限制问题,因为值的大小可能会有所变化(它仅针对集合的最大长度)。Redis可以通过内存受限的数据库实例和过期键来完整地完成所有操作。因此,有更多的选择。 - jdi

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接