Redis之Scan

1 介绍

Scan 实际上是keys的升级版

  1. 可以用keys来查询key,在查询的过程中,可以使用通配符。keys虽然用着还算方便,但是没有分页功能。同时因为Redis是单线程,所以key的执行会比较消耗时间,特别是当数据流大的时候,影响整个程序的运行。
  2. 为了解决keys存在的问题,从Redis2.8中开始,引入了Scan(通过游标分布执行)
  3. Scan具备keys的功能,但是不会阻塞线程,而且可以控制每次返回的结果数。

2 基本用法

首先准备数据:

public class ScanTest {
    public static void main(String[] args) {
        Redis redis = new Redis();
        redis.exectu(jedis -> {
            for (int i = 0; i <500 ; i++) {
                jedis.set("k"+i,"v"+i);
            }
        });
    }
}

scan命令一共提供了三个参数:

  • 第一个参数是cursor,第二个参数是key,第三个参数是limit。(Redis里面的数据存储和MySQL的存储差不多,一样是一维数组加链表
  • cursor实际上是指一位数组的位置索引,limit则是遍历的一位数组个数(即数组里面的某个位置的那个链表的数据),所以每次返回的数据大小可能不确定
127.0.0.1:6379> scan 0 match k5* count 500
1) "383"
2)  1) "k52"
    2) "k51"
    3) "k50"
    4) "k55"
    5) "k53"
    6) "k54"
    7) "k57"
    8) "k56"
    9) "k5"
   10) "k58"
   11) "k59"

"383"是下一次要遍历的cursor,下一次查询用这个即可

3 原理

scan的遍历顺序。

假设目前有三条数据:

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> set db_number v1
OK
127.0.0.1:6379> set key1 key1
OK
127.0.0.1:6379> set myKey myKey
OK
127.0.0.1:6379> scan 0 match * count 1
1) "2"
2) 1) "key1"
   2) "db_number"
127.0.0.1:6379> scan 2 match * count 1
1) "1"
2) 1) "myKey"
127.0.0.1:6379> scan 1 match * count 1
1) "0"
2) (empty list or set)

在遍历的过程中,大家发现游标的顺序是 0 2 1,从二进制来看,好像没有规律,但是转为二进制,则是有规律的:

00->10->01->11

这种规律就是高位进1,传统的二进制加法,是从右往左加,这里是从左往右加。

实际上,在Redis中,他的具体计算流程是这样:

  1. 将要计算的数字反转
  2. 给反转后的数字加1
  3. 再反转
00反转00加一01反转10
10反转01加一101+1=210)反转01
01      10       01       11

那么为什么不是按照0、1、2、3、4…这样的顺序遍历呢?

因为主要考虑到两个问题:

  1. 字典扩容(不会查询到重复的数据)
  2. 字典缩容

在这里插入图片描述
假如我们将要访问110时,发送了扩容,此时scan就会从0110开始遍历,之前已经被遍历的元素就不会被遍历了。

假如我们将要访问110时,发生缩容,此时scan就会从10开始遍历,这个时候,也会遍历到010,但是010之前的不会再被遍历了。所以,在发生缩容的时候,可能会返回重复的元素。

4 其他用法

scan是一系列的指令,除了遍历所有key之外,也可以遍历某一个类型的key,对应的命令有:

//对应
zscan->zset
hscan->hset
sscan->set
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值