在前面的文章 Redis删除大key时为什么会阻塞中,有说到,不应该直接调用 del 命令删除key,容易造成请求被阻塞,那应该如何来处理呢?
这次从代码编写的角度来举例说明下。
在Redis中,有几个比较特殊的结构String,List、Hash、Set、ZSet, 从Redis删除大key时为什么会阻塞中文章可以知道,不能直接del (除了string),而应该使用 scan的方式,而每一个类型也都有自己的scan 方式。接下来以 Java Jedis 为例。
List
String key = "demo";
int length = jedis.llen("demo");
if (length > 1024) {
int size = 100;
int count = 0;
do {
//每次处理前100个
// redis内部也会判断当前传递的索引有没有超过当前的list的长度
// 可参阅 ltrimCommand
jedis.ltrim(key, 0, size);
count += size;
}
while (count < length);
}
jedis.del(key);Set
String key = "demo";
long length = jedis.scard(key);
if (length > 1024) {
//每次遍历100个
ScanParams scanParams = new ScanParams().count(100);
// 传递的游标
java.lang.String cursor = "0";
ScanResult<String> sscan;
do {
//传递 scan的参数
sscan = jedis.sscan(key, cursor, scanParams);
if (!CollectionUtils.isEmpty(sscan.getResult())) {
// 遍历返回的结果,依次删除
sscan.getResult().stream().forEach(member -> {
jedis.srem(key, member);
});
}
// 传入下次遍历的游标
cursor = sscan.getCursor();
} while (!sscan.isCompleteIteration());
}
jedis.del(key);ZSet
String key = "demo";
// 获取zset的长度
long length = jedis.zcard(key);
if (length > 1024) {
int size = SIZE;
int count = 0;
do {
// 删除指定的集合
jedis.zremrangeByRank(key, 0, size);
count += size;
}
while (count < length);
}
jedis.del(key);Hash
String key = "demo";
// 获取Hash的字段个数
long length = jedis.hlen(key);
if (length > THROLD) {
ScanParams scanParams = new ScanParams();
// 遍历大小
scanParams.count(SIZE);
// 匹配哪些字段
scanParams.match("*");
ScanResult<Map.Entry<String, String>> result;
java.lang.String cursor = "0";
do {
// 遍历字段
result = jedis.hscan(key, cursor, scanParams);
if (!CollectionUtils.isEmpty(result.getResult())) {
// 删除指定的字段
result.getResult().stream().forEach(x -> {
jedis.hdel(key, x.getKey());
});
}
cursor = result.getCursor();
} while (!result.isCompleteIteration());
}
jedis.del(key);到此这篇关于Redis 大key的几种删除方式的文章就介绍到这了,更多相关Redis 大key删除内容请搜索站长网以前的文章或继续浏览下面的相关文章希望大家以后多多支持站长网!





