springboot3 redis 批量删除特定的 key 或带有特定前缀的 key

在 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 自动过期机制,减少手动删除的需求。

相关推荐
远方16091 小时前
14-Oracle 23ai Vector Search 向量索引和混合索引-实操
数据库·ai·oracle
GUIQU.2 小时前
【Oracle】数据仓库
数据库·oracle
恰薯条的屑海鸥2 小时前
零基础在实践中学习网络安全-皮卡丘靶场(第十六期-SSRF模块)
数据库·学习·安全·web安全·渗透测试·网络安全学习
咖啡啡不加糖2 小时前
Redis大key产生、排查与优化实践
java·数据库·redis·后端·缓存
曼汐 .2 小时前
数据库管理与高可用-MySQL高可用
数据库·mysql
MickeyCV2 小时前
使用Docker部署MySQL&Redis容器与常见命令
redis·mysql·docker·容器·wsl·镜像
2301_793102493 小时前
Linux——MySql数据库
linux·数据库
喵叔哟3 小时前
第4章:Cypher查询语言基础
数据库
刘 大 望3 小时前
数据库-联合查询(内连接外连接),子查询,合并查询
java·数据库·sql·mysql
从零开始学习人工智能3 小时前
Doris 数据库深度解析:架构、原理与实战应用
数据库·架构