代码之家  ›  专栏  ›  技术社区  ›  JHH

使用redis从有限范围生成唯一ID

  •  2
  • JHH  · 技术社区  · 6 年前

    我有一些数据库项,除了它们的主键之外,还需要一个对这些项所属的组唯一的索引。我们叫房地产吧 nbr 以及将项组合在一起并定义唯一 丁腈橡胶 我们会打电话 group . 这个 丁腈橡胶 必须在[1-n]范围内,并且 可以 从外部源导入项时设置。因为所有项目都必须 丁腈橡胶 然后,任务将变成如何跟踪使用的值,以便能够选择一个自由值。 丁腈橡胶 对于手动添加的新项目。

    我使用的是dynamodb和redis。我不能打开dynamodb索引 丁腈橡胶 . 到目前为止,我的想法是使用redis跟踪特定组中使用了哪些数字,以便对redis键(如 <MYGROUP>-item-nbrs 我可以把所有用过的 丁腈橡胶 :s并实现逻辑以查找下一个空闲 丁腈橡胶 . 使用范围内的孔 丁腈橡胶 是可以接受的,但在考虑耗尽的数量之前,应填充孔。

    实际上,我想找到一个最大大小为n的稀疏数组的未使用索引。

    在Redis中存储这些信息以快速找到免费的 丁腈橡胶 ?到目前为止,我的想法包括:

    • 一个逗号分隔的字符串,所有使用的NBR的排序顺序?找到一个免费的NBR,A GET 发出命令并对字符串进行分析,直到找到一个孔或列表的末尾,将拾取的数字插入到字符串中,然后替换整个字符串。当n较大时,这看起来效率很低。

    • 每个人使用的哈希 丁腈橡胶 存储为自己的字段,并使用例如 HSCAN 遍历哈希字段以查找 丁腈橡胶 . 当n较大时,hscan必须扫描很多字段。

    • 分割我的 丁腈橡胶 :s进入名为p1-20、p21-40、p41-60……的字段中,每个字段包含一组已使用的 丁腈橡胶 :s仅在该分区内,当一个分区耗尽时(不再有空闲空间 丁腈橡胶 :s),完全移除它以加速进一步的迭代。使用hscan进行迭代,hset启动新分区。

    • 免费存储 丁腈橡胶 而不是全部使用,使用排序集和zpopmin或常规列表和lpop,可能划分为子集。预填充所有免费的Redis 丁腈橡胶 不过,1-N看起来很难看。

    假设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
      }
    }
    
    1 回复  |  直到 5 年前
        1
  •  1
  •   Kevin Christopher Henry    5 年前

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

    记录数值的使用 SETBIT :

    SETBIT key [nbr] 1
    

    找到一个免费的 丁腈橡胶 使用 BITPOS 以下内容:

    BITPOS key 0
    

    为了避免比赛条件,你需要确保你的get和set是原子的。[手术室在一个 follow-up question 。]

    这将需要很少的内存(对于65536个可能的值,需要8K字节)。 比特波斯 是O(N),但这不太可能是真正的问题。