Redis中列表和集合处理的最佳实践是什么?

9
我们正在使用Redis作为缓存服务器,经常需要处理缓存列表。当我们缓存简单对象时,我们会执行GET操作,如果对象不存在,Redis将返回null,我们就知道该对象没有被缓存,需要从数据库加载。
但是当我们处理列表时,如何更好地处理空列表呢?一个空列表可以是有效值。我们需要调用EXISTS检查列表是否存在(这会使操作变成两个调用而不是一个),还是有人有更好的想法来处理这种情况?
/谢谢
3个回答

9
如果你绝对需要这样做,那么在创建列表时,您可以将一个“标志”作为第一个永远不会被删除的元素推入。为了以原子方式执行此操作,您可以使用MULTI/EXEC/WATCH,但是watch仅适用于Redis 2.2,它目前是预览版(即使非常稳定,您可以从github主分支中获取)。
我认为在您的用例中,您可能还需要RPUSHX和LPUSHX,这将仅在列表已经存在时原子地推送。
请注意,自Redis 2.2以来,“存在”意味着列表至少有1个元素,因为将达到零元素的列表会自动删除,出于许多很好的原因 ;)

1
经过进一步考虑,我认为我的解决方案将是简单地不在运行时自动重新生成列表。我担心的是:我将记录插入数据库,并同时添加到 Redis 列表中。如果 Redis 发生崩溃(并且可能会丢失最后一秒的交易),那么我怎样才能使数据库和 Redis 再次同步。我想我找到了一个解决方案,意味着如果 Redis 发生崩溃,情况就必须通过从数据库重新同步列表来手动恢复。哦 - 谢谢你的好工作 :-) - Micael
1
+1 作为正确答案。但你能告诉我你的“好理由”吗?空集和列表与不存在的不同。 - Chris Pfohl

3

很不幸,像LRANGE和SMEMBERS这样的列表/集合检索命令似乎不能区分空列表/集合和不存在的列表/集合。

因此,如果您绝对需要区分这两种情况,我想您需要先进行EXISTS检查。尝试使用管道化命令以获得更好的性能。大多数Redis客户端库都支持管道化。

或者您可以重新考虑缓存策略,以便您不需要区分它们。


自从v2.0版本以来,Redis将空的LIST、SET、ZSET和HASHE与不存在的一样处理。当您从列表中删除所有元素时,EXISTS命令将返回false! - Ludger Sprenker
@Ludger Sprenker 哇,我不知道这个!之前我只测试过1.2.6。这完全破坏了Micael的缓存策略。 - kijin

-1
如果您正在使用PHP,我建议将返回值分配给一个变量,然后检查它是否为数组。(这是使用Predis库的工作方式)
$res = $redis->get('Key');
if(is_array($res))
    do code here

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