Redis 线上环境导出所有的 key
一、问题:
查询 redis 所有的 key 是工作中经常能遇到的问题,如果线上环境,你直接使用 keys *,恭喜你,可以去填单子了~真正的操作方式是使用 redis 提供的 scan 命令来处理,下面笔者用 java 程序来实现导出所有的 key。
二、SCAN
介绍:
SCAN 命令用于迭代当前数据库中的数据库键,SCAN 支持增量式迭代, 它们每次执行都只会返回少量元素, 所以这些命令可以用于生产环境, 而不会出现像 KEYS 命令、 SMEMBERS 命令带来的问题 —— 当 KEYS 命令被用于处理一个大的数据库时, 又或者 SMEMBERS 命令被用于处理一个大的集合键时, 它们可能会阻塞服务器达数秒之久
可用版本:
>= 2.8.0
时间复杂度:
增量式迭代命令每次执行的复杂度为 O(1) , 对数据集进行一次完整迭代的复杂度为 O(N) , 其中 N 为数据集中的元素数量。
三、线上环境导出所有键的 JAVA 代码
RedisUtil.java
package com.gameboys.sniper;
import java.util.List;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
/**
* Description:
*
* @author www.gameboys.cn
* @date 2019年12月13日
*/
public class RedisUtil {
public static void getAllKeys(Jedis jedis) {
String cursor = ScanParams.SCAN_POINTER_START;
String key = "*";
ScanParams scanParams = new ScanParams();
scanParams.match(key);// 匹配以* 为前缀的 key
scanParams.count(1000);
while (true) {
// 使用scan命令获取500条数据,使用cursor游标记录位置,下次循环使用
ScanResult scanResult = jedis.scan(cursor, scanParams);
cursor = scanResult.getStringCursor();// 返回0 说明遍历完成
List list = scanResult.getResult();
for (String string : list) {
System.out.println(string + " \t" + jedis.type(string) + " \t" + jedis.ttl(string));
}
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
if ("0".equals(cursor)) {
break;
}
}
System.out.println("ok");
}
}
四.总结
线上环境导出所有的 rediskey 信息,不能使用 keys 命令,可以使用 scan 命令迭代导出