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

相关推荐
马尔代夫哈哈哈4 小时前
Spring IoC&DI
数据库·sql
液态不合群5 小时前
[特殊字符] MySQL 覆盖索引详解
数据库·mysql
计算机毕设VX:Fegn08956 小时前
计算机毕业设计|基于springboot + vue蛋糕店管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
瀚高PG实验室6 小时前
PostgreSQL到HighgoDB数据迁移
数据库·postgresql·瀚高数据库
打码人的日常分享7 小时前
智能制造数字化工厂解决方案
数据库·安全·web安全·云计算·制造
三水不滴7 小时前
Redis 过期删除与内存淘汰机制
数据库·经验分享·redis·笔记·后端·缓存
-孤存-8 小时前
MyBatis数据库配置与SQL操作全解析
数据库·mybatis
2301_822366358 小时前
使用Scikit-learn构建你的第一个机器学习模型
jvm·数据库·python
万邦科技Lafite10 小时前
一键获取京东商品评论信息,item_reviewAPI接口指南
java·服务器·数据库·开放api·淘宝开放平台·京东开放平台
自可乐10 小时前
Milvus向量数据库/RAG基础设施学习教程
数据库·人工智能·python·milvus