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

相关推荐
lssjzmn6 分钟前
针对不同使用场景,Redis的Value应该如何序列化,优缺点如何,进来看
spring boot·redis
鱼骨不是鱼翅19 分钟前
redis---set详解
redis
工业甲酰苯胺19 分钟前
Redis支持事务吗?了解Redis的持久化机制吗?
数据库·redis·bootstrap
NineData1 小时前
NineData 最新发布 SQL Server 双向实时同步功能
数据库·后端·架构
手握风云-1 小时前
MySQL数据库精研之旅第十一期:打造高效联合查询的实战宝典(二)
数据库·mysql
Jasonakeke2 小时前
【重学MySQL】八十九、窗口函数的分类和使用
数据库·mysql
云飞云共享云桌面2 小时前
共享云服务器替代传统电脑做三维设计会卡顿吗
大数据·运维·服务器·数据库·自动化
倔强的石头1062 小时前
数据对话的“通用语法”:SQL与KingbaseES的智能处理艺术
数据库·sql
我科绝伦(Huanhuan Zhou)3 小时前
浅聊达梦数据库物理热备的概念及原理
数据库·oracle
zhz52144 小时前
从PostgreSQL到人大金仓(KingBase)数据库迁移实战:Spring Boot项目完整迁移指南
数据库·spring boot·postgresql