redis删除key模糊匹配_Redis大key问题

d85a8b2881526659e5de99cde6160f02.png

5b2700ba1e0c95d12ebd65b30246ae7d.gif//Redis大key问题小节//

    在Redis中,大key指的是key对应的value值所占的内存空间比较大,例如一个字符串类型的value最大可以存储512MB的内容,一个列表类型的value最多可以存储2的32次方-1个元素,一般情况下,我们认为字符串类型的key的value值超过10kb,就算大key。

01 大key的危害

   大key带来的危害体现在三个方面:

内存空间不均匀、

操作耗时,存在阻塞风险、

网络阻塞,每次获取大key产生的网络流量较大。

如果一个key的大小为1MB,每秒访问量为1000,那么每秒会产生1000MB的流量。这对于普通千兆网卡的服务器来说是灾难性的。

02 如何发现大key

1、redis-cli --bigkeys命令可以统计bigkey的分布情况。

2、使用debug object key命令,从命令结果中的serializedlength的值来判断当前key的字节数

3、使用strlen命令来判断当前key的长度

4、使用scan命令+debug object结合起来,scan命令可以渐进的扫描所有的key值,分别计算每个key的serializedlength值,找到对应的bigkey进行相应的处理和报警。这个操作尽量在从库进行,因为debug object命令执行速度可能会比较慢,造成Redis的阻塞。

5、通过python脚本迭代的scan key,对每次scan的内容进行判断

6、redis-rdb-tools工具。redis实例上执行bgsave,然后对dump出来的rdb文件进行分析,找到其中的大KEY

03 大key如何处理?

   我们知道del命令可以直接删除键,但是当我们知道了大key的危害后,我们应该意识到大key不能直接使用del命令进行清理。

对于string类型,经测试,不同大小对应的删除时间如下:

512kb   0.22ms

1MB     0.31ms

2MB     0.32ms

5MB     0.56ms

10MB   1ms

string类型的大key,建议不要存入Redis,因为每次调用都会产生比较严重的性能影响。

对于其他类型,可以使用scan命令循序渐进的删除或者进行大key拆分。

scan命令每次只扫描所有key的部分内容,它用来代替keys * 语法,从而缓解keys * 可能点来的性能问题。scan命令的语法如下:

scan cursor [match pattern] [count pattern]

其中,cursor是必须参数,代表一个游标

match pattern是可选参数,作用是做模式匹配

count pattern是可选参数,表明每次要遍历的键的个数,默认值是10

    还有另外一种思路是对大key进行拆分,将大key拆分为多个key,然后利用mget的方法获取值,或者将大的value拆分到一个hash中,使用hget去获取值。举个例子:

例如原来的

hash_key:{filed1:value, filed2:value, filed3:value ...},

明显field过多,对于field过多的场景,可以根据field进行hash取模,生成一个新的key,可以hash取模后形成如下key:value形式

hash_key:mod1:{filed1:value}

hash_key:mod2:{filed2:value}

hash_key:mod3:{filed3:value}

通过取模,将原先单个key分成多个key,每个key field个数为原先的1/N

    在Redis中,要特别注意复杂度为O(n)的操作,这类操作一般时间较长,很容易阻塞Redis,在集群环境下极易发生故障切换。

143230afacef040eb0e10d966f4fe432.pngc1424d4717eb46f1ed7a71df80b3d40e.png有帮助的话还希望点下再看哈

版权声明:本文为weixin_39968640原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。