Spring Boot中如何用@CacheEvict删除Redis前缀匹配的所有Key?
Spring Boot Redis 删除指定前缀缓存的解决方案
1. 是否可以通过@CacheEvict实现该需求?
不行。Spring Cache的@CacheEvict注解的key属性仅支持指定具体的缓存键值,不支持通配符(比如*)的模糊匹配。你尝试的两种写法(直接拼接*或SpEL表达式里写objectKey*)都不符合Spring Cache的语法规则,自然无法生效。另外,@CacheEvict的allEntries = true参数只能清空整个value指定的缓存空间,也做不到按前缀精准匹配删除。
2. 若无法通过@CacheEvict实现,该如何达成目标?
推荐直接基于RedisTemplate操作,结合Redis的SCAN命令(避免KEYS命令的性能问题)来实现前缀匹配删除,以下是两种可行方案:
方案一:基础SCAN遍历删除
@Autowired private RedisTemplate<String, Object> redisTemplate; public void dropCacheByPrefix(String prefix) { // 构造扫描规则,匹配前缀开头的所有Key ScanOptions scanOptions = ScanOptions.scanOptions() .match(prefix + "*") .count(100) // 每次扫描返回的Key数量,可根据实际调整 .build(); // 执行SCAN遍历 Cursor<String> cursor = redisTemplate.executeWithStickyConnection(connection -> connection.scan(scanOptions)); try { while (cursor.hasNext()) { redisTemplate.delete(cursor.next()); } } finally { cursor.close(); // 务必关闭游标释放资源 } }
注意:不要用
KEYS命令,它会遍历Redis所有Key,在数据量大时会阻塞Redis服务,生产环境必须用SCAN命令分批遍历。
方案二:批量删除优化(适合大量Key场景)
如果匹配到的Key数量较多,可积累到一定数量后批量删除,提升效率:
@Autowired private RedisTemplate<String, Object> redisTemplate; public void dropCacheByPrefix(String prefix) { ScanOptions scanOptions = ScanOptions.scanOptions() .match(prefix + "*") .count(100) .build(); Cursor<String> cursor = redisTemplate.executeWithStickyConnection(connection -> connection.scan(scanOptions)); List<String> keyBatch = new ArrayList<>(1000); // 批量删除的阈值 try { while (cursor.hasNext()) { keyBatch.add(cursor.next()); if (keyBatch.size() >= 1000) { redisTemplate.delete(keyBatch); keyBatch.clear(); } } // 删除剩余的Key if (!keyBatch.isEmpty()) { redisTemplate.delete(keyBatch); } } finally { cursor.close(); } }
内容的提问来源于stack exchange,提问作者Kartik Gautam
相关产品推荐
相关产品推荐

