Redis-SCAN命令

一、背景

由于Redis是单线程的,因此在使用一些像KEYS、SMEMBERS等时间复杂度为O(N)的命令时,数据量大的键就会阻塞进程,导致Redis卡顿。

Redis在2.8版本之后增加了SCAN命令:

SCAN cursor [MATCH pattern] [COUNT count]

SCAN及相关命令:

  • SCAN 命令用于迭代当前数据库中的数据库键
  • SSCAN 命令用于迭代集合键(Set)中的元素
  • HSCAN 命令用于迭代哈希键(Hash)中的键值对
  • ZSCAN 命令用于迭代有序集合(Sorted Set)中的元素(包括元素成员和元素分值)

优点:

  • SCAN命令每次执行的复杂度为 O(1) ,虽然一次完整迭代的复杂度也是 O(N) ,但它是分次进行的,不会阻塞线程
  • SCAN命令提供了limit参数,可以控制每次返回结果的最大条数

缺点:

  • 对键进行增量式迭代的过程中,如果数据有修改,可能会造成结果的重复,对查询结果只能提供有限的保证(Redis使用了reverse binary iteration算法,保证数据只会重复,不会遗漏)
  • 每次返回的数据条数不一定,极度依赖内部实现

二、用法

  1. 基础命令
    SCAN 命令是一个基于游标的迭代器(cursor based iterator):SCAN命令每次被调用之后,都会向用户返回一个新的游标,用户在下次迭代时需要使用这个新游标作为SCAN命令的游标参数,以此来延续之前的迭代过程。当SCAN命令的游标参数被设置为0时,服务器将开始一次新的迭代, 而当服务器向用户返回值为0的游标时,表示迭代已结束。
// 第一次请求
10.0.1.61-共用开发环境:1>scan 0
1)"7"
2)1)   "key1"
  2)   "Akey9"
  3)   "Bkey12"
  4)   "Akey10"
  5)   "key5"
  6)   "Bkey11"
  7)   "Akey7"
  8)   "key3"
  9)   "Akey8"
  10)  "key2"
 
 
// 第二次请求
10.0.1.61-共用开发环境:1>scan 7
1)"0"
2)1)   "key4"
  2)   "Akey6"
  1. MATCH选项
    和KEYS命令一样,SCAN命令的MATCH选项是一个通配符参数
// 第一次请求
10.0.1.61-共用开发环境:1>scan 0 MATCH key*
1)"7"
2)1)   "key1"
  2)   "key5"
  3)   "key3"
  4)   "key2"
// 第二次请求
10.0.1.61-共用开发环境:1>scan 7 MATCH key*
1)"0"
2)1)   "key4"
  1. COUNT选项
    COUNT 选项只是对增量式迭代命令的一种提示(hint),但是在大多数情况下,这种提示都是有效的(在数据量少的情况下,COUNT值与返回的结果数量不相等)。
10.0.1.61-共用开发环境:1>scan 0 MATCH key* COUNT 1
1)"8"
2)1)   "key1"

三、JAVA RedisTemplate 中的应用

/**
 * count可以直接写死为固定数值
 */
 
 
@Resource(name = "redisTemplate_15")
private RedisTemplate redis;
 
 
// SCAN 命令
public List<String> sCan(String match, Integer count) {
    List<String> result = new ArrayList<>();
    try {
        Set<String> key = new HashSet<>();
        Cursor<byte[]> cursor = redis.getConnectionFactory().getConnection().scan(
                ScanOptions.scanOptions().match(match).count(count).build()
        );
 
        while (cursor.hasNext()) {
            result.add(new String(cursor.next()));
        }
        cursor.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return result;
}
 
 
// SSCAN 命令
public List<String> sSCan(String key, String match, Integer count) {
    List<String> result = new ArrayList<>();
    try {
        Cursor<String> cursor = redis.opsForSet().scan(key,
                ScanOptions.scanOptions().match(match).count(count).build()
        );
        while (cursor.hasNext()) {
            result.add(cursor.next());
        }
        cursor.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return result;
}
 
 
// HSCAN 命令
public Map<String, String> hSCan(String key, String match, Integer count) {
    Map<String, String> result = new HashMap<>(0);
    try {
        Cursor<Map.Entry<String, String>> cursor = redis.opsForHash().scan(key,
                ScanOptions.scanOptions().match(match).count(count).build()
        );
        while (cursor.hasNext()) {
            Map.Entry<String, String> cursorMap = cursor.next();
            result.put(cursorMap.getKey(), cursorMap.getValue());
        }
        cursor.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return result;
}
 
 
// ZSCAN 命令
public Set<ZSetOperations.TypedTuple<String>> zSCan(String key, String match, Integer count) {
    Set<ZSetOperations.TypedTuple<String>> result = new HashSet<>();
    try {
        Cursor<ZSetOperations.TypedTuple<String>> cursor = redis.opsForZSet().scan(key,
                ScanOptions.scanOptions().match(match).count(count).build()
        );
        while (cursor.hasNext()) {
            result.add(cursor.next());
        }
        cursor.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return result;
}
Redis 中,`redis-cli` 是一个命令行客户端工具,用于与 Redis 服务器进行交互。如果你想查看缓存(即键值对)的状态,可以使用以下 `redis-cli` 命令: 1. `INFO` 命令:这是一个通用的命令,可以提供大量关于 Redis 服务器的信息,包括内存使用、连接信息等。其中 `info keyspace` 或 `info memory` 子命令可以显示与缓存相关的部分。 ```sh redis-cli info keyspace redis-cli info memory ``` 2. `KEYS` 命令:虽然不是专门用于查看缓存的,但你可以使用它来查找所有存储的键。注意这个命令在生产环境中不推荐使用,因为它可能消耗大量资源。 ```sh redis-cli KEYS "*" (查找所有键) ``` 3. `SCAN` 命令:这个命令用于遍历整个数据库,并返回匹配给定模式的键。通常用于批量操作,但也可以用来查看缓存。 ```sh redis-cli scan ``` 4. `HGETALL` (或 `MGET`) 命令:如果使用的是哈希类型的数据结构,你可以获取特定哈希表的所有键值对。 ```sh redis-cli HGETALL myhash ``` 5. `LRANGE` 或 `LRANGE key start end`:如果使用的是有序集合(Sorted Set),可以查看指定范围内的元素。 ```sh redis-cli LRANGE myzset 0 -1 ``` 请根据你的具体需求选择合适的命令,但要注意在生产环境中谨慎使用 `KEYS` 和 `SCAN`,因为它们可能会影响性能。如果你需要详细了解缓存的详细统计和配置,`INFO` 命令通常是最佳选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值