redis-scan-rehash

Scan正则表达式

在平时线上 Redis 维护工做中,有时候须要从 Redis 实例成千上万的 key 中找出特定前缀的 key 列表来手动处理数据,多是修改它的值,也多是删除 key。这里就有一个问题,如何从海量的 key 中找出知足特定前缀的 key 列表来?算法

keys * 正则表达式匹配数组

  1. 没有 offset、limit 参数,一次性吐出全部知足条件的 key,万一实例中有几百 w 个 key 知足条件,当你看到满屏的字符串刷的没有尽头时,你就知道难受了。
  2. keys 算法是遍历算法,复杂度是 O(n),若是实例中有千万级以上的 key,这个指令就会致使 Redis 服务卡顿,全部读写 Redis 的其它的指令都会被延后甚至会超时报错,由于 Redis 是单线程程序,顺序执行全部指令,其它指令必须等到当前的 keys 指令执行完了才能够继续

scan 相比 keys 具有有如下特色:服务器

  1. 复杂度虽然也是 O(n),可是它是经过游标分步进行的,不会阻塞线程;
  2. 提供 limit 参数,能够控制每次返回结果的最大条数,limit 只是一个 hint,返回的结果可多可少;
  3. 同 keys 同样,它也提供模式匹配功能;
  4. 服务器不须要为游标保存状态,游标的惟一状态就是 scan 返回给客户端的游标整数;
  5. 返回的结果可能会有重复,须要客户端去重复,这点很是重要;
  6. 遍历的过程当中若是有数据修改,改动后的数据能不能遍历到是不肯定的;
  7. 单次返回的结果是空的并不意味着遍历结束,而要看返回的游标值是否为零;

scan 参数提供了三个参数,第一个是 cursor 整数值,第二个是 key 的正则模式,第三个是遍历的 limit hint。第一次遍历时,cursor 值为 0,而后将返回结果中第一个整数值做为下一次遍历的 cursor。一直遍历到返回的 cursor 值为 0 时结束。遍历顺序:高位进位加法spa

127.0.0.1:6379> scan 0 match key99* count 1000

渐进式 rehash

Java 的 HashMap 在扩容时会一次性将旧数组下挂接的元素所有转移到新数组下面。若是 HashMap 中元素特别多,线程就会出现卡顿现象。Redis 为了解决这个问题,它采用渐进式 rehash线程

它会同时保留旧数组和新数组,而后在定时任务中以及后续对 hash 的指令操做中渐渐地将旧数组中挂接的元素迁移到新数组上。这意味着要操做处于 rehash 中的字典,须要同时访问新旧两个数组结构。若是在旧数组下面找不到元素,还须要去新数组下面去寻找。code

scan 也须要考虑这个问题,对与 rehash 中的字典,它须要同时扫描新旧槽位,而后将结果融合后返回给客户端。字符串

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息