「这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战」
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