java实现删除redis千万级数据的大key

针对Redis中千万级大Key删除难题,本文介绍如何利用scan命令避免阻塞问题,确保服务稳定运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

redis删除千万级大key问题处理-20171017

 

1、问题描述

redis数据存储了几千万的数据的key,使用del无法删除,占用大量redis内存,且会导致redis切机
 

2、问题分析

redis使用del每秒可清理100w~几百万个值,假如是几千万的大数据量的key时,会导致redis阻塞10秒以上,sentinel会检测redis状态判断redis故障,而进行切换,应用程序也会在这期间连不上redis而崩溃,所以需分批处理,别因删除数据而阻塞redis,从而导致程序故障。
 

3、问题处理

redis v2.8以上推出了scan命令,以时间复杂度为O(1)的方式,遍历包含n个元素的大key,避免使用单个O(n)的大key命令,导致redis阻塞,java实现代码为:

public boolean delLargeHashKey(String key, int scanCount) throws Exception{
        boolean broken = false;
        Jedis jedis = pool.getSentineJedis();
        try{
        if (jedis!=null)
        {
                ScanParams scanParameters = new ScanParams();

                                         //一次获取500条,可自定义条数
                scanParameters.count(scanCount);
                String cursor = "";
                while ((!cursor.equals("0")) || (cursor == "0")){
                
                //使用hscan命令获取500条数据,使用cursor游标记录位置,下次循环使用
                ScanResult<Map.Entry<String, String>> hscanResult=jedis.hscan(key, cursor, scanParameters);
                cursor = hscanResult.getStringCursor();// 返回0 说明遍历完成
                List<Map.Entry<String, String>> scanResult = hscanResult.getResult();
                long t1 = System.currentTimeMillis();
                for(int m = 0;m < scanResult.size();m++){  
                    Map.Entry<String, String> mapentry  = scanResult.get(m);
                    //System.out.println("key: "+mapentry.getKey()+"  value: "+mapentry.getValue());
                    jedis.hdel(key, mapentry.getKey());
                    }
                long t2 = System.currentTimeMillis();
                System.out.println("删除"+scanResult.size()+"条数据,耗时: "+(t2-t1)+"毫秒,cursor:"+cursor);
                }
                return true;
        }
        return false;
    }catch (JedisException e) {
        broken = pool.handleJedisException(e);
        if (broken) {
            pool.closeResource(jedis, broken);
        }
        throw e;
    } finally {
        if (!broken && jedis != null) {
            pool.sentinel_close(jedis);
        }
    }
    }
已经在使用中,删除大key无任何异常,且速度很快

如果您觉得我的文章给了您帮助,请为我买一杯饮料吧!以下是我的支付宝,意思一下我将非常感激!

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咫尺的梦想ing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值