【问题标题】:What is best practice for list and set handling in Redis?Redis 中列表和集合处理的最佳实践是什么?
【发布时间】:2011-05-01 17:35:35
【问题描述】:

我们使用 Redis 作为缓存服务器,经常要处理缓存列表。当我们缓存简单对象时,我们会执行 GET,如果对象不存在,Redis 将返回 null,我们会知道该对象没有被缓存并且必须从数据库中加载。

但是我们如何最好地处理列表 - 一个空列表可以是一个有效值。我们是否需要调用 EXISTS 来检查列表是否存在(但进行操作 2 次调用而不是一次调用)还是有人知道如何处理这种情况?

/谢谢

【问题讨论】:

    标签: redis


    【解决方案1】:

    如果您绝对需要这样做,则在创建列表时,您可以将“哨兵”作为第一个永远不会删除的元素推送。为了以原子方式执行此操作,您可以使用 MULTI/EXEC/WATCH,但 watch 仅在 Redis 2.2 中可用,目前是预览版(即使相当稳定,您也可以从 github master 分支获取)。

    我认为在您的用例中,您可能还需要 RPUSHX 和 LPUSHX,它们只会在列表已经存在时自动推送列表。

    请注意,由于 Redis 2.2 的存在意味着列表至少有 1 个元素,因为出于许多充分的理由,将自动删除将达到零元素的列表;)

    【讨论】:

    • 经过更多考虑后,我认为我的解决方案是不自动重新生成列表。我关心的是:我在数据库中插入一条记录,并同时添加到 Redis 列表中。如果 Redis 发生崩溃(并且可能丢失最后一秒的事务) - 我怎么能达到数据库和 Redis 再次同步的状态。我想我已经找到了一个解决方案,这意味着如果 Redis 发生崩溃,则必须通过重新同步数据库中的列表来手动恢复这种情况。哦-感谢您的出色工作:-)
    • +1 表示正确答案。但是你能指出我的“充分理由”吗?空集和列表与不存在的不同。
    【解决方案2】:

    不幸的是,LRANGE 和 SMEMBERS 等列表/集检索命令似乎无法区分空列表/集和不存在的列表/集。

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

    或者你可能会重新考虑你的缓存策略,这样你就不需要区分它们了。

    【讨论】:

    • 从 v2.0 开始,redis 对待空 LIST、SET、ZSET 和 HASHE 的方式与不存在的相同。从列表中删除所有元素后,EXISTS 命令将返回 false!
    • @Ludger Sprenker 哇,我不知道!我之前只用 1.2.6 测试过这个。这完全搞砸了 Micael 的缓存策略。
    【解决方案3】:

    如果您使用的是 php,我会将返回值分配给一个变量,然后检查它是否是一个数组。 (这是使用 Predis 库的工作原理)

    $res = $redis->get('Key');
    if(is_array($res))
        do code here
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-27
      • 2010-10-15
      • 1970-01-01
      • 2019-07-12
      • 2013-10-15
      • 1970-01-01
      • 2011-09-22
      相关资源
      最近更新 更多