1、 双重判断加锁的懒汉式Bean
package com.XXX.cloud.platfrom.common.redis.util;
import com.XXX.cloud.common.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.ConvertingCursor;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.serializer.RedisSerializer;
import java.util.HashSet;
import java.util.Set;
/**
* @Description: redis缓存key操作工具类
* @ClassName: RedisKeyUtils
* @Date: 2020/4/29 8:53
* @Version: 1.0
*/
@Slf4j
public class RedisKeyBean {
private RedisTemplate<String, Object> redisTemplate;
private static RedisKeyBean redisKeyBean = null;
private RedisKeyBean(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
/**
* 双重判断加锁的懒汉式
* @param redisTemplate
* @date 2020/4/29 9:29
* @version 1.0
*/
public static RedisKeyBean getInstance(RedisTemplate<String, Object> redisTemplate) {
if (redisKeyBean == null) {
synchronized (RedisKeyBean.class) {
if (redisKeyBean == null) {
redisKeyBean = new RedisKeyBean(redisTemplate);
}
}
}
return redisKeyBean;
}
/**
* 根据preKey前缀获取redis的缓存key
* @param preKey
* @date 2020/4/29 9:14
* @version 1.0
*/
public Set<String> scanRedisKeys(String preKey) {
try {
long start = System.currentTimeMillis();
// 需要匹配的key
String patternKey = preKey + "*";
ScanOptions options = ScanOptions.scanOptions()
// 这里指定每次扫描key的数量(很多博客瞎说要指定Integer.MAX_VALUE,这样的话跟keys有什么区别)
.count(10000)
.match(patternKey).build();
RedisSerializer<String> redisSerializer = (RedisSerializer<String>) redisTemplate.getKeySerializer();
Cursor cursor = (Cursor) redisTemplate.executeWithStickyConnection(redisConnection -> new ConvertingCursor<>(redisConnection.scan(options), redisSerializer::deserialize));
Set<String> result = new HashSet<>();
while(cursor.hasNext()){
result.add(cursor.next().toString());
}
// 切记这里一定要关闭,否则会耗尽连接数。报Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisException: Could not get a
cursor.close();
log.info("scan扫描共耗时:{}ms,key数量:{}", System.currentTimeMillis()-start, result.size());
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 批量删除preKey前缀的缓存
* @param preKey
* @date 2020/4/29 9:21
* @version 1.0
*/
public void deleteRedisKeysByPre(String preKey) {
if (StringUtil.isNotBlank(preKey)) {
Set<String> redisKeys = scanRedisKeys(preKey);
redisTemplate.delete(redisKeys);
}
}
}
2、调用
// 获取操作缓存key的Bean
RedisKeyBean redisKeyBean = RedisKeyBean.getInstance(redisTemplate);
redisKeyBean.deleteRedisKeysByPre("your preKey");