redis集群如何清理前缀相同的key
最近经常收到redis集群告警,每天收到50多封邮件,实在不胜其烦,内存不够用,原因是有一些无用的key(约3000万)占用内存(具体不说了)。这部分内存不能被释放。
原来的定期清理脚本的逻辑:
打开一个redis链接,在内部循环从1000万到7亿之间的数据,然后加上前缀去批量删除,这种方式属于广撒网式的清理,穷举法,不但耗时,效果也不好。
因为有的数字在redis中可能不存在,而且更重要的一点,如果有超过7亿的数字,这部分数据不会被清除,扩展性很差。
(1)那么如何清理呢?redis集群没有keys这种方法,那么如何能快速准确地定位到这批key呢?
我们可以根据RedisCluster集群提供的getClusterNodes方法,获取到这个redis-cluster的每个节点,然后再去逐个遍历节点,获取节点的Jedis对像,使用单个jedis对像
再去获取前缀相同的keys
(2)获取到key集合之后,再遍历这些key,使用JedisClusterCRC16.getSlot(key)方法,定位到key所在的slot,把在同一个slot的key批量删除,这样做,第一能保证需要删的key都存在于redis集群,第二批量删除,提高效率。
具体代码:
Map<String, JedisPool> clusterNodes = jedis.getClusterNodes();
String keysPattern = keyPrefix + ":*";
long countX = 0;
long sTime = System.currentTimeMillis();
for (Map.Entry<String, JedisPool> entry : clusterNodes.entrySet()) {
Jedis jedisNode = entry.getValue().getResource();
logger.info("redisip:{},port:{}" , jedisNode.getClient().getHost(), jedisNode.getClient().getPort());
if (!jedisNode.info("replication").contains("role:slave")) {
Set<String> keys = jedisNode.keys(keysPattern);
logger.info("keys长度:{}" , keys.size());
Map<Integer, List<String>> map = new HashMap<>(6600);
long countTmp = 0;
for (String key : keys) { int slot = JedisClusterCRC16.getSlot(key);
/**
* cluster模式执行多key操作的时候,这些key必须在同一个slot上,
* 不然会报:JedisDataException
*/
//按slot将key分组,相同slot的key一起提交
if (map.containsKey(slot)) {
map.get(slot).add(key);
} else {
List<String> keyList = new ArrayList<String>();
keyList.add(key);
map.put(slot, keyList);
} }
long count = 0;
for (Map.Entry<Integer, List<String>> integerListEntry : map.entrySet()) {
count += jedisNode.del(integerListEntry.getValue().toArray(new String[integerListEntry.getValue().size()]));
logger.info("删除:{}个",count);
countX++;
}
}
}
// logger.info("删除完成,共删除:{}个",countX);
logger.info("删除userid key任务结束,一共删除key数量:{},耗时:{}", countX , System.currentTimeMillis() - sTime);
redis集群如何清理前缀相同的key的更多相关文章
- Bash实践:抽样检测数据迁移至Redis集群后的数据一致性
熟悉了一段时间的Bash编程,因此借此任务操作一把bash编程,主要涉及到Redis单节点与Redis集群的操作 1. 任务背景 近日有个任务需要将历史的Redis(主从节点)中的数据迁移至Redis ...
- 使用DBeaver Enterprise连接redis集群的一些操作记录
要点总结: 使用DBeaver Enterprise连接redis集群可以通过SQL语句查看key对应的value,但是没法查看key. 使用RedisDesktopManager连接redis集群可 ...
- Redis集群最佳实践
今天我们来聊一聊Redis集群.先看看集群的特点,我对它的理解是要需要同时满足高可用性以及可扩展性,即任何时候对外的接口都要是基本可用的并具备一定的灾备能力,同时节点的数量能够根据业务量级的大小动态的 ...
- Couchbase集群和Redis集群解析
Couchbase集群和Redis集群解析 首先,关于一些数据库或者是缓存的集群有两种结构,一种是Cluster;一种是master-salve. 关于缓存系统一般使用的就是Redis,Redis是开 ...
- phpredis Redis集群 Redis Cluster
官方url: https://github.com/phpredis/phpredis/blob/develop/cluster.markdown#readme 2017年10月29日20:44:25 ...
- redis集群主流架构方案分析
Redis在互联网大数据平台有着广泛的应用,主要被用来缓存热点数据,避免海量请求压垮数据库,同时可以提升服务节点的响应速度和并发量.随着数据量的增多,由于redis是占用单台物理机或虚机的内存,内存资 ...
- Redis(七)-- SpringMVC整合Redis集群
1.pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www ...
- Redis 集群使用(2)
Redis包含三种集群策略: 主从复制 哨兵模式 redis cluster 主从复制 在主从复制中,数据分为两类:主数据库(master)和 从数据库(slave).其中主从复制有如下特点: 主数据 ...
- Spring集成Redis集群(含spring集成redis代码)
代码地址如下:http://www.demodashi.com/demo/11458.html 一.准备工作 安装 Redis 集群 安装参考: http://blog.csdn.net/zk6738 ...
随机推荐
- Jensen 不等式
若f(x)为区间I上的下凸(上凸)函数,则对于任意xi∈I和满足∑λi=1的λi>0(i=1,2,...,n),成立: \[f(\sum ^{n} _{i=1} \lambda _{i}x_{i ...
- Flask中对MySQL的基本操作
在Flask-SQLAlchemy中,插入.修改.删除操作,均由数据库会话管理. 会话用 db.session 表示.在准备把数据写入数据库前,要先将数据添加到会话中然后调用 commit() 方法提 ...
- python list统计
from random import randint data = [randint(0, 20) for _ in xrange(30)] print data # [20, 4, 4, 20, 1 ...
- spring配置多个视图解析
<!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceVie ...
- js | javascript获取和设置元素的属性
获取和设置元素的内容: var nv = document.getElementById("pid"); alert(nv.innerHTML); nv.innerHTML=&qu ...
- 基于socketserver模块实现并发的套接字(tcp、udp)
tcp服务端:import socketserver class MyHandler(socketserver.BaseRequestHandler): def handle(self): #通信循环 ...
- bootStrap的轮播
1.1如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...
- SQL中EXCEPT函数在 Mysql 和 sqlServer 中的替代方法
示例摘自:极客代码:http://wiki.jikexueyuan.com/project/sql/useful-functions/except-clause.html EXCEPT 子句 EXCE ...
- 【linux基于Postfix和Dovecot邮件系统的搭建】
一:PostFixe和Dovecot的简单介绍 Postfix postfix是Wietse Venema在IBM的GPL协议之下开发的MTA(邮件传输代理)软件.postfix是Wietse Ven ...
- MySQL innodb表使用表空间物理文件复制或迁移表
MySQL InnoDB引擎的表通过拷贝物理文件来进行单表或指定表的复制,可以想到多种方式,今天测试其中2种: 将innodb引擎的表修改为Myisam引擎,然后拷贝物理文件 直接拷贝innodb的表 ...