1.scan和keys
都是遍历获取key的。 keys: 简单粗暴会返回所有匹配的key。当key过多的时候阻塞,会会造成服务器卡顿,所有后续执行redis的命令会延时或者超时报错。 scan: 1、复杂度虽然也是 O(n),但是它是通过游标分步进行的,不会阻塞线程; 2、提供 limit 参数,可以控制每次返回结果的最大条数,limit 只是一个 hint,返回的 结果可多可少; 3、同 keys 一样,它也提供模式匹配功能; 4、服务器不需要为游标保存状态,游标的唯一状态就是 scan 返回给客户端的游标整数; 5、返回的结果可能会有重复,需要客户端去重复,这点非常重要; 6、遍历的过程中如果有数据修改,改动后的数据能不能遍历到是不确定的; 7、单次返回的结果是空的并不意味着遍历结束,而要看返回的游标值是否为零; 复制代码
2.scan命令
2.1命令
scan cursor MATCH pattern COUNT count 复制代码
2.2.scan例子说明
scan 0 match key* count 2 第一次迭代使用 `0` 作为游标, 表示开始一次新的迭代。 返回的第一条数据为槽位,标识下一次开始的地方,直到返回为0标识结束。 count 2 标识的是槽位数,而不是返回的条数 复制代码
网络异常,图片无法展示
|
2.3sand的遍历和扩容
从上面对图可以看出scan返回的槽位数据是从大到小,也就是从高位到低位。 这样做是为了扩容和缩容的时候避免槽位的遗漏和重复 复制代码
网络异常,图片无法展示
|
首先容量是2的N次方,扩容或者缩容的时候都是2的倍数。 a 1 001 1%8=1 1%16=1 b 6 110 6%8=6 6%16=6 c 3 011 3%8=3 扩大一倍后 3%16=3 d 14 1110 14%8=6 14%16=14 e 11 1011 11%8=3 11%16=11 f 11 1011 11%8=3 11%16=11 可以看到d、e、f的槽位发生了变化 高位到低位 00 10 01 11 000 100 010 110 001 101 011 111 遍历到01的时候扩容那么会从 001 开始遍历,前面已经遍历过的数据则不会再遍历了。 复制代码
2.4redis扩容-》渐进式 rehash
2.5大key定位指令
redis-cli -a 123654 --bigkeys redis-cli -a 123654 --bigkeys -i 0.1 上面这个指令每隔 100 条 scan 指令就会休眠 0.1s