在 Redis 中存储大量相似项目的随机列表

发布于 2024-10-19 07:01:58 字数 344 浏览 4 评论 0原文

Redis 2.0.3

我需要在 Redis 中存储大量的项目列表。每个项目都是一个短字符串(少于 256 个字符)。

我需要在列表上执行两项操作:

  • 添加许多(几千到一百万)相同的项目。 (一天几次)

  • 从列表中随机删除一项。没有必要有“公平”的随机性。任何“足够好”的方法都可以。 (每秒最多数百次)

我没有足够的 RAM 来将列表中的所有项目一一存储。

我认为我需要批量存储物品,名称和柜台。 (将有多达数千个不同的项目,更像是数百个。)

但我不确定如何有效地组织它。

有什么提示吗?

Redis 2.0.3

I need to store a huge list of items in Redis. Each item is a short string (less than 256 characters).

I need to do two operations on the list:

  • Add many (several thousands to a million) identical items. (Several times a day)

  • Remove one random item from the list. It is not necessary to have "fair" random. Any "good enough" approach will do. (Up to several hundred times a second)

I do not have enough RAM to store all items in a list one by one.

I think that I need to store items in batches, name and a counter. (There will be up to several thousands distinct items, more like several hundreds.)

But I'm not sure how to organize this effectively.

Any hints?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无所谓啦 2024-10-26 07:01:58

好吧,既然没有人愿意帮助我,这里有一个伪代码的“愚蠢”解决方案。

  1. 获取随机元素:

    函数 Maybe_get_next_item()
      item_name = SRANDMEMBER "项目集"
      item_key = "项目:" + item_name
    
      new_item_count = DECR(item_key)
    
      如果 new_item_count <那么 0
        LOCK——如 SETNX 文档中所述
          new_item_count = GET (item_key) -- 当我们锁定时添加更多内容?
          如果 new_item_count 和 new_item_count <那么 0
            SREM (item_name) -- 不,让它过期
          结尾
        开锁
      结尾
    
      如果 new_item_count 和 new_item_count >= 0 那么
        返回项目名称
      结尾
    
      返回 false -- 未找到该项目
    结尾
    
    函数 get_next_item()
      item_name = Maybe_get_next_item()
      而不是 item_name 且 (SCARD "items-set" > 0) 执行
        item_name = Maybe_get_next_item()
      结尾
      return item_name -- 如果所有项目都已消耗则返回 false
    结尾
    
  2. 插入新元素

    函数 insert_items(item_name, amount)
      LOCK——如 SETNX 文档中所述
        SADD“项目集”(项目名称)
        INCRBY(“商品:”+商品名称)金额
      开锁
    结尾
    

如果存在,请提出更好的解决方案,我仍在摸索Redis,并且可能会错过一些明显的东西。

我怀疑 insert_items() 中的 LOCK/UNLOCK 可能是多余的,可以用 MULTI/EXEC,但我认为 maybe_get_next_item() 中的 LOCK/UNLOCK 需要它才能正常工作(我确实这样做)不知道如何替换为 MULTI/EXEC)...

Well, since nobody is up to help me, here is a "dumb" solution, in pseudocode.

  1. Get random element:

    function maybe_get_next_item()
      item_name = SRANDMEMBER "items-set"
      item_key = "items:" + item_name
    
      new_item_count = DECR (item_key)
    
      if new_item_count < 0 then
        LOCK -- As explained in SETNX docs
          new_item_count = GET (item_key) -- More added while we were locking?
          if new_item_count and new_item_count < 0 then
            SREM (item_name) -- No, expire it
          end
        UNLOCK
      end
    
      if new_item_count and new_item_count >= 0 then
        return item_name
      end
    
      return false -- this item not found
    end
    
    function get_next_item()
      item_name = maybe_get_next_item()
      while not item_name and (SCARD "items-set" > 0) do
        item_name = maybe_get_next_item()
      end
      return item_name -- false if all items are expended
    end
    
  2. Insert new elements

    function insert_items(item_name, amount)
      LOCK -- As explained in SETNX docs
        SADD "items-set" (item_name)
        INCRBY ("items:" + item_name) amount
      UNLOCK
    end
    

Please do suggest a better solution if it exists, I'm still groking Redis, and may miss something obvious.

I suspect that LOCK/UNLOCK in insert_items() may be superfluous and can be replaced with MULTI/EXEC, but I think that it is needed for LOCK/UNLOCK in maybe_get_next_item() to work properly (which I do not know how to replace with MULTI/EXEC)...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文