在 Spring Boot 3 中与 Redis 一起使用时,可以通过 Redis 的命令来实现批量删除特定的 Key 或带有特定前缀的 Key。以下是实现方式和注意事项。
使用 RedisTemplate
RedisTemplate 是 Spring Boot 提供的一个操作 Redis 的工具,支持各种 Redis 操作。
批量删除指定的 Key
java
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 {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public void deleteKeys(Set<String> keys) {
redisTemplate.delete(keys);
}
}
调用示例:
java
@Autowired
private RedisService redisService;
Set<String> keys = Set.of("key1", "key2", "key3");
redisService.deleteKeys(keys);
批量删除特定前缀的 Key
Redis 不直接支持通配符删除,但可以使用 keys 命令获取匹配的 Key,然后删除它们。
java
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 {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public void deleteKeysWithPrefix(String prefix) {
// 获取匹配的 key
Set<String> keys = redisTemplate.keys(prefix + "*");
if (keys != null && !keys.isEmpty()) {
redisTemplate.delete(keys);
}
}
}
调用示例:
java
@Autowired
private RedisService redisService;
redisService.deleteKeysWithPrefix("user:"); // 删除所有以 "user:" 开头的 key
注意事项
keys 命令的性能问题:
keys 命令会扫描整个 Redis 数据库,可能会导致性能问题,尤其是数据量较大时。
在生产环境中,推荐使用 SCAN 命令代替 keys。
使用 SCAN 替代 KEYS
SCAN 是一种分段扫描的方式,可以避免一次性加载大量 Key。
java
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 {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public void deleteKeysWithPrefix(String prefix) {
List<String> keysToDelete = new ArrayList<>();
// 使用 SCAN 命令逐步获取匹配的 key
try (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();
}
// 删除所有匹配的 key
if (!keysToDelete.isEmpty()) {
redisTemplate.delete(keysToDelete);
}
}
}
调用示例:
java
@Autowired
private RedisService redisService;
redisService.deleteKeysWithPrefix("session:");
使用 Lua 脚本批量删除(推荐)
Lua 脚本可以在 Redis 服务端高效地执行删除操作。
java
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 {
@Autowired
private 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 自动过期机制,减少手动删除的需求。