1、前提
因为项目需要redis一些老数据做删除操作,大概30w数据,当时想的是用keys命令把数量一次性拿出来,但是keys会造成线程的阻塞,所以选择使用scan命令进行操作
2、发现问题
当我在本地使用scan命令的时候,发现我测试环境明明有1000条数据,我每次count的条数是100条,但是惊奇的发现返回的总数居然不是100条,而是79条数据。
这个时候我就怀疑应该是我没有理解到count机制的问题,然后就去翻阅官网,果然找到了答案。:
由此可以看到,count并不一定能返回用户所指定的数量。既然如此,那么这个count到底做了什么尼。
3、在网上找到了一篇我认为还比较好的解答
从上面的解释就可以看出,count其实并不是返回的是数量集合,而是查询数据的时候进行的字典槽数量。
4、什么是字典槽
在 Redis 中所有的 key 都存储在一个很大的字典中,这个字典的结构和 Java 中 的 HashMap 一样,是一维数组 + 二维链表结构,
第一维数组的大小总是 2^n (n>=0),扩容一次数组大小空间加倍,也就是 n++。
scan 指令返回的游标就是第一维数组的位置索引,我们将这个位置索引称为槽 (slot)。
如果不考虑字典的扩容缩容,直接按数组下标挨个遍历就行了。
limit 参 数就表示需要遍历的槽位数,之所以返回的结果可能多可能少,是因为不是所有 的槽位上都会挂接链表,
有些槽位可能是空的,还有些槽位上挂接的链表上的元 素可能会有多个。每
一次遍历都会将 limit 数量的槽位上挂接的所有链表元素进 行模式匹配过滤后,一次性返回给客户端。