本文主要是介绍java实现删除redis千万级数据的大key,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
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无任何异常,且速度很快
如果您觉得我的文章给了您帮助,请为我买一杯饮料吧!以下是我的支付宝,意思一下我将非常感激!
这篇关于java实现删除redis千万级数据的大key的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!