记一次redis使用keys

本文记录了一次在生产环境中慎用Redis KEYS命令的经历,由于其可能导致性能下降和阻塞,作者建议使用SCAN命令作为替代方案。文中详细分析了KEYS命令的问题及其对大型数据库的影响,并提供了使用SCAN命令的优点和相关代码示例。
摘要由CSDN通过智能技术生成

记一次redis使用keys

使用场景:项目启动时,索引所有redis缓存删除后重新录入

代码分析:

redisTemplete.keys("*");

优化原因:不能用于生产环境

官方文档描述:

Warning: consider KEYS as a command that should only be used in production environments with extreme care. It may ruin performance when it is executed against large databases. This command is intended for debugging and special operations, such as changing your keyspace layout. Don’t use KEYS in your regular application code. If you’re looking for a way to find keys in a subset of your keyspace, consider using sets.

原因:

  • KEYS命令的性能随着数据库数据的增多而越来越慢
  • KEYS命令会引起阻塞,连续的 KEYS命令足以让 Redis 阻塞,尤其是redis存在big value类型数据时

解决方案:使用scan命令

优点:实现同样的功能,不会造成redis阻塞

代码:

		/**
     * scan 实现
     *
     * @param pattern  表达式
     * @param consumer 对迭代到的key进行操作
     */
    public void scan(String pattern, Consumer<byte[]> consumer) {
        this.stringRedisTemplate.execute((RedisConnection connection) -> {
            try (Cursor<byte[]> cursor = connection.scan(ScanOptions.scanOptions().count(Long.MAX_VALUE).match(pattern).build())) {
                cursor.forEachRemaining(consumer);
                return null;
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        });
    }

    /**
     * 获取符合条件的key
     *
     * @param pattern 表达式
     * @return
     */
    public Set<String> keys(String pattern) {
        Set<String> keys = new HashSet<>();
        this.scan(pattern, item -> {
            //符合条件的key
            String key = new String(item, StandardCharsets.UTF_8);
            keys.add(key);
        });
        return keys;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值