【问题标题】:Use Redis to generate unique ID from a limited range使用 Redis 从有限范围内生成唯一 ID
【发布时间】:2023-04-08 03:55:01
【问题描述】:

我有数据库项目,除了它们的主键外,还需要一个对项目所属组唯一的索引。我们将属性称为nbr,将项目组合在一起并定义唯一nbr 的范围的属性我们将称为groupnbr 必须在 [1-N] 范围内,并且可以在从外部源导入项目时设置。由于所有项目都必须有一个nbr,因此任务就变成了如何跟踪使用了哪些值,以便为手动添加的新项目选择一个免费的nbr

我正在使用 DynamoDB 和 Redis。我无法在 nbr 上创建 DynamoDB 索引。到目前为止,我的想法是使用 Redis 跟踪哪些数字已用于特定组,这样对于 Redis 键,例如 <MYGROUP>-item-nbrs,我可以存储所有使用的 nbr:s 并实现逻辑来查找下一个免费nbr。使用的nbr 范围内的孔是可以接受的,但在考虑用尽数量之前应填充孔。

基本上我想找到一个最大大小为 N 的稀疏数组的未使用索引。

将这些信息存储在 Redis 中以快速找到免费的nbr 的良好结构是什么?到目前为止,我的想法包括:

  • 按排序顺序包含所有使用的 nbr 的单个逗号分隔字符串?为了找到一个空闲的 nbr,发出一个GET 命令并解析字符串,直到找到一个洞或列表的末尾,选择的号码被插入到字符串中,然后整个字符串被替换。当 N 很大时,这似乎非常低效。

  • 每个使用 nbr 的哈希存储为自己的字段,并使用例如HSCAN 遍历哈希字段以找到免费的nbr。当 N 很大时,HSCAN 必须扫描很多字段。

  • 将我的nbr:s 分区为称为 p1-20、p21-40、p41-60、...的字段,每个字段仅包含该分区内使用的 nbr:s 的排序集,并且当一个分区用尽时(不再有免费的nbr:s),将其完全删除以加快进一步的迭代。使用 HSCAN 进行迭代,使用 HSET 启动新分区。

  • 存储所有空闲的nbr,而不是全部使用,并使用排序集和 ZPOPMIN 或常规列表和 LPOP,可能划分为子集。不过,用所有免费的nbr 1-N 预填充 Redis 看起来很丑。

假设 N 的大小为 65536。

出于性能或其他原因,上述任何解决方案是否更好/更差?有没有更好/更智能的方法,也许利用我不知道的 Redis 的一些聪明方面?

编辑:

Kevin 的回答导致了以下解决方案(伪代码):

function getFreeNbr() {
  while (true) {
    send "WATCH numbers"
    nbr = send "BITPOS numbers 0"

    if nbr < N
      send "MULTI"
      send "SETBIT numbers $nbr 1"
      if send "EXEC" != NULL
        return nbr
      end if
    else 
      send "UNWATCH numbers"
      return -1
    end if
  }
}

【问题讨论】:

    标签: algorithm redis sparse-matrix


    【解决方案1】:

    如何使用Bitmaps 记录每个可能的nbr,是否使用该值?

    要记录一个值被使用,请使用SETBIT

    SETBIT key [nbr] 1
    

    要找到免费的nbr,请使用BITPOS

    BITPOS key 0
    

    为避免竞争条件,您需要确保 get-and-set 是原子的。 [OP 在follow-up question 中解决了这个问题。]

    这将需要很少的内存(65536 个可能值需要 8K 字节)。 BITPOS 是 O(n),但这不太可能是一个真正的问题。

    【讨论】:

    • 这看起来很有希望,好主意!非常感谢,我一定会调查的。
    • 我根据您的建议更新了问题,作为伪代码,包括处理原子性。再次感谢。
    • 聚会迟到了,但我会使用 INCR。原子的、可预设的、快速的、良好的
    猜你喜欢
    • 2019-09-29
    • 1970-01-01
    • 2012-10-24
    • 2011-08-02
    • 1970-01-01
    • 1970-01-01
    • 2012-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多