redis没有提供可以直接使用的,需要自己封装:

不能使用keys ,而是使用scan

Redis命令

对应的命令:

1
2
3
4
5
redis-cli --raw keys "*prefix*" | xargs redis-cli del

# SCAN cursor [MATCH pattern] [COUNT count]
redis-cli --scan --pattern "*prefix*" | xargs -L 2000 redis-cli del
# 其中xargs -L指令表示xargs一次读取的行数,也就是每次删除的key数量,一次读取太多xargs会报错

类似的SCAN命令,对于Redis不同的数据类型还有另外几个SSCAN、HSCAN和ZSCAN,使用方法类似:

sscan ops-coffee 0 MATCH v1*

java 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//redis-cli --raw keys "ops-coffee-*" | xargs redis-cli del
//直接在linux下通过redis的keys命令匹配到所有的key,然后调用系统命令xargs来删除,看似非常完美,实则风险巨大

// 因为Redis的单线程服务模式,命令keys会阻塞正常的业务请求,如果你一次keys匹配的数量过多或者在del的时候遇到大key,
// 都会直接导致业务的不可用,甚至造成redis宕机的风险
// 所以我们在生产环境中应当避免使用上边的方法,那有什么优雅的方法来解决呢?SCAN!
// 按照模糊匹配批量删除
public boolean deleteWithScan(String key) {
Jedis jedis = null;
String cursor = "0";

List<String> list = null;
try {
jedis = jedisPool.getResource();
ScanParams params = new ScanParams();
params.match(key);
params.count(100);
while (true) {
ScanResult scanResult = jedis.scan(cursor, params);
list = scanResult.getResult();
if (!CollectionUtils.isEmpty(list)) {
String[] array = list.toArray(new String[0]);
jedis.del(array);
}
log.info(" 本轮 Scan 查到的待删除数据集是 ============ " + list);
cursor = scanResult.getCursor();
if ("0".equals(cursor)) {
break;
}
}

return true;
} finally {
returnToPool(jedis);
}
}

参考:

Redis删除特定前缀key的优雅实现

https://juejin.cn/post/6844903869412016142#comment

java实现有点问题,所有使用scan查询出来之后全部删除

https://www.cnblogs.com/east7/p/11665392.html