在 Spring Boot 3 中与 Redis 一起使用时,可以通过 Redis 的命令来实现批量删除特定的 Key 或带有特定前缀的 Key。以下是实现方式和注意事项。
使用 RedisTemplate
RedisTemplate 是 Spring Boot 提供的一个操作 Redis 的工具,支持各种 Redis 操作。
批量删除指定的 Key
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import java.util.Set;@Service
public class RedisService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;public void deleteKeys(Set<String> keys) {redisTemplate.delete(keys);}
}
调用示例:
@Autowired
private RedisService redisService;Set<String> keys = Set.of("key1", "key2", "key3");
redisService.deleteKeys(keys);
批量删除特定前缀的 Key
Redis 不直接支持通配符删除,但可以使用 keys 命令获取匹配的 Key,然后删除它们。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import java.util.Set;@Service
public class RedisService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;public void deleteKeysWithPrefix(String prefix) {// 获取匹配的 keySet<String> keys = redisTemplate.keys(prefix + "*");if (keys != null && !keys.isEmpty()) {redisTemplate.delete(keys);}}
}
调用示例:
@Autowired
private RedisService redisService;redisService.deleteKeysWithPrefix("user:"); // 删除所有以 "user:" 开头的 key
注意事项
keys 命令的性能问题:
keys 命令会扫描整个 Redis 数据库,可能会导致性能问题,尤其是数据量较大时。
在生产环境中,推荐使用 SCAN 命令代替 keys。
使用 SCAN 替代 KEYS
SCAN 是一种分段扫描的方式,可以避免一次性加载大量 Key。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import java.util.ArrayList;
import java.util.List;@Service
public class RedisService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;public void deleteKeysWithPrefix(String prefix) {List<String> keysToDelete = new ArrayList<>();// 使用 SCAN 命令逐步获取匹配的 keytry (Cursor<byte[]> cursor = redisTemplate.executeWithStickyConnection(redisConnection -> redisConnection.scan(ScanOptions.scanOptions().match(prefix + "*").count(1000).build()))) {if (cursor != null) {cursor.forEachRemaining(key -> keysToDelete.add(new String(key)));}} catch (Exception e) {e.printStackTrace();}// 删除所有匹配的 keyif (!keysToDelete.isEmpty()) {redisTemplate.delete(keysToDelete);}}
}
调用示例:
@Autowired
private RedisService redisService;redisService.deleteKeysWithPrefix("session:");
使用 Lua 脚本批量删除(推荐)
Lua 脚本可以在 Redis 服务端高效地执行删除操作。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import java.util.Collections;@Service
public class RedisService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;public void deleteKeysWithPrefix(String prefix) {String script = "local keys = redis.call('keys', ARGV[1]) " +"for i=1,#keys,5000 do " +" redis.call('del', unpack(keys, i, math.min(i+4999, #keys))) " +"end " +"return keys";redisTemplate.execute((RedisConnection connection) -> connection.eval(script.getBytes(), ReturnType.INTEGER, 0, (prefix + "*").getBytes()));}
}
总结
小数据集:可以直接使用 keys 和 RedisTemplate 的 delete。
大数据集:推荐使用 SCAN 或 Lua 脚本来批量处理 Key。
生产环境优化:
避免频繁使用通配符操作,建议对 Redis 数据设计时尽量减少需要批量操作的场景。
配合 Redis 的 TTL 自动过期机制,减少手动删除的需求。