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

相关推荐
Super Rookie14 分钟前
MongoDB 自动化脚本安装方案
数据库·mongodb·自动化
Code哈哈笑20 分钟前
【MongoDB 基本语法】数据库和集合的基本操作--探秘 MongoDB
数据库·mongodb
恋红尘38 分钟前
Redis面试八股
数据库·redis·面试
creator_Li1 小时前
缓存行Cache Line
缓存
直有两条腿2 小时前
【数据迁移】HBase Bulkload批量加载原理
大数据·数据库·hbase
言之。2 小时前
ClickHouse 数据更新策略深度解析:突变操作与最佳实践
服务器·数据库·clickhouse
白衣鸽子3 小时前
数据库高可用设计的灵魂抉择:CAP权衡
数据库·后端
DokiDoki之父4 小时前
Mybatis—入门 & (配置)SQL提示和日志输出
数据库·sql·mybatis
阿维的博客日记5 小时前
Redis学习笔记-QuickList
redis·笔记·学习
TDengine (老段)5 小时前
TDengine 数据函数 LN 用户手册
大数据·数据库·物联网·时序数据库·tdengine·涛思数据