1 定义
redis大key其实不是指的是key,而是指key对应的value。
redis的string类型,最大可以存512mb的值,list、hash、set、zset等,可以存储232个元素(大约42亿多点),那么多大的key算大key呢?
一般来说,我们string需要控制在10kb以下,而集合类型的控制元素个数在5000个以下。
2 如何导致的大key
一种,比如社交类的场景,如粉丝数增多,另外一种,可能由于报表等常年累月的积累,有可能导致大key。
我们知道,由于redis工作线程是单线程的,大key删除会导致网络浏览阻塞、超时等一系列问题,那么我们就应该去防止大key的产生
3 如何检测大key
一般来说,有两种方法:
- 使用
--bigkeys
:扫描所有的键,给出每种数据结构top 1 bigkey
[root@localhost ~]# redis-cli -a redis密码 --bigkeys warning: using a password with '-a' or '-u' option on the command line interface may not be safe. # scanning the entire keyspace to find biggest keys as well as # average sizes per key type. you can use -i 0.1 to sleep 0.1 sec # per 100 scan commands (not usually needed). [00.00%] biggest string found so far '"k5889"' with 5 bytes [00.00%] biggest string found so far '"k607267"' with 7 bytes [00.00%] biggest string found so far '"k1802564"' with 8 bytes [50.00%] sampled 1000000 keys so far [100.00%] sampled 2000000 keys so far -------- summary ------- sampled 2000000 keys in the keyspace! total key length in bytes is 14888896 (avg len 7.44) biggest string found '"k1802564"' has 8 bytes 0 lists with 0 items (00.00% of keys, avg size 0.00) 0 hashs with 0 fields (00.00% of keys, avg size 0.00) 2000000 strings with 14888896 bytes (100.00% of keys, avg size 7.44) 0 streams with 0 entries (00.00% of keys, avg size 0.00) 0 sets with 0 members (00.00% of keys, avg size 0.00) 0 zsets with 0 members (00.00% of keys, avg size 0.00)
- 使用
memery usage
:获取一个键的所占内存
127.0.0.1:6379> memory usage k10000 (integer) 64
4 大key的删除
4.1 string类型
string类型一般用del
即可,如果过于庞大可以使用unlink
4.2 hash类型
使用hscan
每次获取少量field-value
,再使用hdel
删除每个field
public void delbighash(string bighashkey) { scanparams scanparams = new scanparams().count(100); string cursor = "0"; do { scanresult<entry<string, string>> scanresult = jedis.hscan(bighashkey, cursor, scanparams); list<entry<string, string>> entrylist = scanresult.getresult(); if (collectionutils.isnotempty(entrylist)) { for (entry<string, string> entry : entrylist) { jedis.hdel(bighashkey, entry.getkey()); } } cursor = scanresult.getcursor(); } while (!"0".equals(cursor)); jedis.del(bighashkey); }
4.3 list类型
使用ltrim
渐进式逐步删除,直到全部删除完成
public void delbiglist(string biglistkey){ long llen = jedis.llen(biglistkey); int counter = 0; int left = 100; while (counter < llen) { jedis.ltrim(biglistkey, left, llen); counter += left; } jedis.del(biglistkey); }
4.4 set类型
使用sscan
每次获取部分元素,再使用srem
命令删除每个元素
public void delbigset(string bigsetkey){ scanparams scanparams = new scanparams().count(100); string cursor = "0"; do { scanresult<string> scanresult = jedis.sscan(bigsetkey, cursor, scanparams); list<string> memberlist = scanresult.getresult(); if (collectionutils.isnotempty(memberlist)) { for (string member : memberlist) { jedis.srem(bigsetkey, member); } } cursor = scanresult.getcursor(); } while (!"0".equals(cursor)); jedis.del(bigsetkey); }
4.5 zset类型
使用zscan
每次获取部分元素,再使用zremrangebyrank
命令删除每个元素
public void delbigzset(string bigzsetkey){ scanparams scanparams = new scanparams().count(100); string cursor = "0"; do { scanresult<tuple> scanresult = jedis.zscan(bigzsetkey, cursor, scanparams); list<tuple> tuplelist = scanresult.getresult(); if (collectionutils.isnotempty(tuplelist)) { for (tuple tuple : tuplelist) { jedis.zrem(bigzsetkey, tuple.getelement()); } } cursor = scanresult.getcursor(); } while (!"0".equals(cursor)); jedis.del(bigzsetkey); }
到此这篇关于redis 大key的删除的实现策略的文章就介绍到这了,更多相关redis 大key删除内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论