(五)Redis的sacn

redis指令keys指令用于列出所有满足特定正则字符串规则的key

两个缺点:

  1. 没有offset,limit参数,一次性吐出所有满足条件的key
  2. 算法是遍历算法,复杂度是O(n),如果有千万级以上的key,这个指令会导致redis卡顿,因为redis是单线程的

为了解决上诉问题redis在2.8中引入了scan,具有以下特点

  • 虽然复杂度也是O(n),但是它通过游标分步进行,不会阻塞线程
  • 提供limit参数,返回结果可控
  • 同样具备匹配功能
  • 返回结果可能重复,需要客户端去重
  • 单次返回的结果为空,不一定意味着遍历结束,需要看游标值是否为0

scan参数:scan 0 match name* count 10

  • cursor:返回为0时将结果中第一个整数值作为下一次遍历的cursor,一直遍历到返回的cursor值为0时结束
  • key的正则模式:
  • 遍历的limit hint
127.0.0.1:6379> keys *
 1) "name3"
 2) "a1"
 3) "name1"
 4) "name2"
 5) "age"
 6) "codehole"
 7) "dd"
 8) "d"
 9) "name"
10) "foo"
11) "a"
127.0.0.1:6379> scan 0 match name* count 10
1) "0"
2) 1) "name3"
   2) "name1"
   3) "name2"
   4) "name"
127.0.0.1:6379> scan 0 match name* count 2
1) "4"
2) 1) "name3"
127.0.0.1:6379> 

原理:

redis的所有key都存储在一个很大的字典中,优点类似于java中的HashMap(一维数组+二维链表),每次扩容空间加倍。

scan指令返回的游标就是一维数组的位置索引,我们将这个位置成为槽(slot),每次遍历会将limit数量的槽位上挂接的所有链表元素进行模式匹配后返回,可能为空!

【遍历算法:高位进位加法】

渐进式rehash

java的hashmap早扩容时会一次性将旧数组下挂载的全部元素转移到新数组下面,如果hashmao中的元素特别多,线程就会出现卡顿,redis为了解决则个问题提出了渐进式rehash

原理:它会同时保存新旧两个数组,然后再定时任务中以及后续对hash的指令操作中渐渐的将旧数组中挂接的元素迁移到新数组中。这意味着要操作处于rehash中的字典,需要同事访问新旧两个数组结构,如果在旧数组下面找不到元素,还要去新数组下面去寻找。

sacn也需要考虑这个问题,对于rehash中的字段,他需要同时扫描新旧槽位,融合后返回给客户端。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值