RedisTemplate.delete(Collection)仅批量删除显式传入的key,不支持通配符;keys()返回空多因keySerializer未设为StringRedisSerializer,需统一序列化方式并慎用KEYS,生产环境推荐SCAN分批处理。
redisTemplate.delete(Collection) 能批量删 key,但不是万能的——它只删你明确传进去的 key 列表,不支持通配符、不触发 FLUSHALL、也不自动查键。用错场景或配置不当,会删不掉、删得慢、甚至 OOM。
常见现象:调用 redisTemplate.keys("user:*") 总是返回空集合,但确认 Redis 里确实有 user:1、user:2 这些 key。
RedisTemplate 的 keySerializer 是 JdkSerializationRedisSerializer,它会对 key 做 Java 序列化(比如加上 xacxedx00x05 前缀),导致 KEYS 命令在服务端匹配不到原始字符串StringRedisSerializer 为 key 序列化器,尤其当你用字符串做 key 时@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); template.setKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); // 其他序列化器按需设置... return template;}
不改这个,keys("user:*") 永远查不到你存进去的字符串 key。
Spring Data Redis 没有内置“删所有匹配前缀的 key”的原子方法,必须手动组合 keys() 和 delete(Collection)。
redisTemplate.keys("order:*") 返回的是 Set<String>,不是 List,可直接传给 delete()
KEYS 是阻塞命令,在大实例上慎用;生产环境建议改用 SCAN + 分批处理(需手写逻辑,RedisTemplate 不封装 SCAN)public void deleteByPrefix(String prefix) { Set<String> keys = redisTemplate.keys(prefix + "*"); if (keys != null && !keys.isEmpty()) { redisTemplate.delete(keys); // 传入 Set,内部转成 pipeline 批量发 DEL }}
别把 keys 结果存 List 再转 Set,多一次遍历没意义;也别对空集合调 delete(),虽然不报错但浪费一次 Redis 往返。
这个方法表面是“批量删”,底层其实是把集合里每个 key 包进一个 DEL 命令,通过 pipeline 发送——不是单条 DEL,也不是 FLUSHDB。
null 或空集合:静默跳过,不抛异常client-output-buffer-limit 限制,或客户端内存飙升(所有 key 都加载到 JVM 堆里)别试图传 "*" 给 delete()——它不会展开通配符,只会去删一个叫 "*" 的 key(几乎不存在)。
如果你的 key 全是字符串(如 "user:1001"),优先用 StringRedisTemplate。
StringRedisTemplate 默认就是 StringRedisSerializer,省去手动配置序列化器的麻烦redisTemplate.keys() 和 stringRedisTemplate.keys() 行为一致,但前者容易因序列化器错配失效delete(Collection) 方法签名和逻辑完全相同,只是泛型约束不同RedisTemplate(JDK 序列化),删除用 StringRedisTemplate(字符串序列化),keys() 查不到,delete() 也删不掉真正关键的不是模板类名,而是 key 序列化方式是否统一。删之前,先确认你写入时用的是哪种序列化器。