删除Redis中keys命令匹配到所有key
|Word count:804|Reading time:3min|Post View:
在开发过程中,经常会遇到Redis的机器内存过高而导致其他服务受到影响,主要原因是没有对一些临时的key设置过期时间或者定期清理,时间一长就会造成很多垃圾数据塞满内存,那么此时就可以通过keys命令将匹配到的key删除。
单节点Redis删除key
单节点不存在槽(slot)
的概念,所以可以直接使用如下命令进行删除
1
| redis-cli keys "*gitlab*"|xargs redis-cli del
|
上面的命令表示删除所有包含gitlab
的key,使用keys *gitlab*
将会得到如下结果:
1 2 3 4 5 6 7 8 9 10 11 12 13
| root@ubuntu:~ 1) "resque:gitlab:cron_job:expire_build_artifacts_worker" 2) "resque:gitlab:cron_job:admin_email_worker:enqueued" 3) "resque:gitlab:stat:failed:2019-07-07" 4) "resque:gitlab:stat:failed" 5) "resque:gitlab:cron_job:repository_check_worker" 6) "resque:gitlab:cron_jobs" 7) "resque:gitlab:stat:processed:2019-07-07" 8) "resque:gitlab:stat:failed:2019-07-07" 9) "resque:gitlab:cron_job:stuck_ci_builds_worker:enqueued" 10) "resque:gitlab:cron_job:repository_archive_cache_worker" 11) "resque:gitlab:cron_job:stuck_ci_builds_worker" 12) "resque:gitlab:processes"
|
那么这些key将会被删除。
当然,有些时候还会有分库的场景,单节点的Redis默认有16
个数据库,那么还可以指定数据库来进行匹配删除,使用-n 数据库编号
即可,例如,删除数据库2
中的所有*gitlab*
的key:
1
| redis-cli -n 2 keys "*gitlab*"| xargs redis-cli -n 2 del
|
Redis Cluster模式删除key
如果Redis是集群的模式,那么此时数据库只能是0
,并且不能使用keys
命令和管道
的组合来匹配删除了,因为数据分布在不同的节点的内存槽里面,需要针对每个节点的key进行删除,此时我们需要借助代码来实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| package xyz.cco.study;
import java.util.HashSet; import java.util.Map; import java.util.Set;
import org.junit.Test;
import redis.clients.jedis.HostAndPort; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisCluster; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig;
public class TestRedisCluster { @Test public void testRedis() { Set<HostAndPort> hostAndPortsSet = new HashSet<>(); hostAndPortsSet.add(new HostAndPort("10.10.170.161", 7000)); hostAndPortsSet.add(new HostAndPort("10.10.170.161", 7001)); hostAndPortsSet.add(new HostAndPort("10.10.170.161", 7002)); hostAndPortsSet.add(new HostAndPort("10.10.170.161", 7003)); hostAndPortsSet.add(new HostAndPort("10.10.170.161", 7004)); hostAndPortsSet.add(new HostAndPort("10.10.170.161", 7005)); JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxIdle(10); jedisPoolConfig.setMaxTotal(30); jedisPoolConfig.setMinIdle(0); jedisPoolConfig.setMaxWaitMillis(200000); jedisPoolConfig.setTestOnBorrow(true);
JedisCluster jedisCluster = new JedisCluster(hostAndPortsSet, jedisPoolConfig); Map<String, JedisPool> clusterNodes = jedisCluster.getClusterNodes(); for (JedisPool pool : clusterNodes.values()) { Jedis jedis = pool.getResource(); Set<String> keySet = jedis.keys("*gitlab*"); for (String key : keySet) { System.out.println(key); if (!key.equals("")) { jedisCluster.del(key); }
} } } }
|
此时就会将每个节点保存的Key进行删除,不过速度比较慢,而且如果在redis的MaxWaitMillis
没有删除完key,会出现保存。如果数据量较大,可以将MaxWaitMillis
设置大一点,目前本程序中设置的200000
毫秒,总共调用了3次,删除了20G的数据。代码中有个判断空的逻辑,我也不清楚为啥读出来有些key是""
,所以就特殊处理了一下。