【问题标题】:Limit list length in redis限制redis中的列表长度
【发布时间】:2012-08-17 02:27:08
【问题描述】:

我正在使用 redis 列表并将新项目推送到列表中。问题是我真的只需要列表中最近的 10 项。

我正在使用 lpush 将项目添加到列表中,并使用 lrange 获取最近的 10 个。

有没有在一定数量之后丢弃物品?我最终会得到可能包含 1,000 项的列表,并且可能会导致延迟出现性能问题。

谢谢!

【问题讨论】:

  • 你是如何与 Redis 交互的?命令行界面? Python? C#?
  • 它应该类似于LTRIM list -10 -1,就像我在下面详细回答的那样。

标签: database redis


【解决方案1】:

在每个 lpush 之后,调用 ltrim 将列表修剪为 10 个元素

http://redis.io/commands/ltrim

【讨论】:

  • 不会检索当前列表长度并仅在长度低于 10 时插入对于大型实体来说是一种性能更好的解决方案吗?
  • @bornSwift,您的解决方案不会保留 10 个最早的条目而不是 10 个最近的条目吗?
  • @TerryLewis,是的,好点。没有看到问题中的“最新”..哎呀
【解决方案2】:

您可以在任何 LPUSH 之后间歇地使用LTRIM无需在每个 LPUSH 之后调用 LTRIM,因为这会增加您应用的整体延迟(尽管 redis 是真的很快,但你可以节省很多 LPUSH 操作)

这是一个伪代码,用于在大约每 5 个 LPUSH 上实现一次 LTRIM:

LPUSH mylist 1
random_int = some random number between 1-5
if random_int == 1:  # trim my list with 1/5 chance
   LTRIM mylist 0 10

虽然您的列表有时可能会增长到超过 10 个元素的几个元素,但它肯定会定期被截断。 这种方法适用于大多数实际目的,并且可以节省大量 LTRIM 操作,从而保持快速推送。

【讨论】:

  • 当一条建议直接来自某人的生产经验时,您几乎可以闻到 ;)
  • 你怎么能确定得到一个随机数并检查它是否比LTRIM调用更昂贵?
  • @fiatjaf 主要是因为 LTRIM 是一种网络操作,但是如果这两个操作都是单个 Lua 脚本的一部分,我们可能需要进行基准测试。但是,我确实强烈地感觉到,在这两种情况下,随机数运算都将比 LTRIM 更简单。
  • @DhruvPathak 如果使用支持流水线的语言/库,则无需编写脚本来节省往返时间。
【解决方案3】:

以下代码,

  • 将项目推送到列表中,
  • 保持大小固定为 10,
  • 并返回最近的 10 个元素

交易中。

MULTI
LPUSH list "item1"
LTRIM list 0 9
LRANGE list 0 9
EXEC

【讨论】:

  • @PaulT.Rawkeen 为什么?它可以通过 Reids 内置命令(包装在事务中)来实现,我看不出有理由让它成为 lua 脚本。
【解决方案4】:

从来没有人提到过只存储最近 10 个项目的真正解决方案。

让我们创建一个包含 15 个项目(这里只是数字)的示例列表:

RPUSH list 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

现在表示距离列表末尾的偏移量:

LTRIM list -10 -1

显示列表

LRANGE list 0 -1

 1) "6"
 2) "7"
 3) "8"
 4) "9"
 5) "10"
 6) "11"
 7) "12"
 8) "13"
 9) "14"
10) "15"

现在您可以添加新项目并运行修剪:

RPUSH list 16
LTRIM list -10 -1

 1) "7"
 2) "8"
 3) "9"
 4) "10"
 5) "11"
 6) "12"
 7) "13"
 8) "14"
 9) "15"
10) "16"

【讨论】:

    【解决方案5】:

    只是一种选择。根据LPUSHofficial doc,它返回推入操作后的列表长度。您可以设置一个阈值长度,如k(在您的情况下 k > 10)并在返回的长度大于k 时调用LTRIM。示例伪代码如下:

    len = LPUSH mylist xxx 
    if len > k:   
      LTRIM mylist 0 9
    LRANGE mylist 0 9
    

    它比随机方法更可控。更大的k 触发更少的LTRIM,但内存成本更高。你可以根据你想要调用LTRIM的频率调整k,因为调用额外的命令更昂贵。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-12
      相关资源
      最近更新 更多