Redis中什么是Big Key(大key)问题?如何解决Big Key问题?

目录

一、什么是Big Key?

二、Big Key产生的场景?

三、Big Key的危害?

四、如何识别Big Key?

五、如何解决Big Key问题?


一、什么是Big Key?

通俗易懂的讲,Big Key就是某个key对应的value很大,占用的redis空间很大,本质上是大value问题。key往往是程序可以自行设置的,value往往不受程序控制,因此可能导致value很大。

redis中这些Big Key对应的value值很大,在序列化/反序列化过程中花费的时间很大,因此当我们操作Big Key时,通常比较耗时,这就可能导致redis发生阻塞,从而降低redis性能。

用几个实际的例子对大Key的特征进行描述:

● 一个String类型的Key,它的值为5MB(数据过大);
● 一个List类型的Key,它的列表数量为20000个(列表数量过多);
● 一个ZSet类型的Key,它的成员数量为10000个(成员数量过多);
● 一个Hash格式的Key,它的成员数量虽然只有1000个但这些成员的value总大小为100MB(成员体积过大);

在实际业务中,大Key的判定仍然需要根据Redis的实际使用场景、业务场景来进行综合判断。通常都会以数据大小与成员数量来判定。

二、Big Key产生的场景?

  • 1、redis数据结构使用不恰当

将Redis用在并不适合其能力的场景,造成Key的value过大,如使用String类型的Key存放大体积二进制文件型数据。

  • 2、未及时清理垃圾数据

没有对无效数据进行定期清理,造成如HASH类型Key中的成员持续不断的增加。即一直往value塞数据,却没有删除机制,value只会越来越大。

  • 3、对业务预估不准确

业务上线前规划设计考虑不足没有对Key中的成员进行合理的拆分,造成个别Key中的成员数量过多。

  • 4、明星、网红的粉丝列表、某条热点新闻的评论列表

假设我们使用List数据结构保存某个明星/网红的粉丝,或者保存热点新闻的评论列表,因为粉丝数量巨大,热点新闻因为点击率、评论数会很多,这样List集合中存放的元素就会很多,可能导致value过大,进而产生Big Key问题。

三、Big Key的危害?

  • 1、阻塞请求

Big Key对应的value较大,我们对其进行读写的时候,需要耗费较长的时间,这样就可能阻塞后续的请求处理。Redis的核心线程是单线程,单线程中请求任务的处理是串行的,前面的任务完不成,后面的任务就处理不了。

  • 2、内存增大

读取Big Key耗费的内存比正常Key会有所增大,如果不断变大,可能会引发OOM(内存溢出),或达到redis的最大内存maxmemory设置值引发写阻塞或重要Key被逐出。

  • 3、阻塞网络

读取单value较大时会占用服务器网卡较多带宽,自身变慢的同时可能会影响该服务器上的其他Redis实例或者应用。

  • 4、影响主从同步、主从切换

删除一个大Key造成主库较长时间的阻塞并引发同步中断或主从切换。

四、如何识别Big Key?

  • 1、使用redis自带的命令识别

例如可以使用Redis官方客户端redis-cli加上--bigkeys参数,可以找到某个实例5种数据类型(String、hash、list、set、zset)的最大key。
    优点是可以在线扫描,不阻塞服务;缺点是信息较少,内容不够精确。

  • 2、使用debug object key命令

根据传入的对象(Key的名称)来对Key进行分析并返回大量数据,其中serializedlength的值为该Key的序列化长度,需要注意的是,Key的序列化长度并不等同于它在内存空间中的真实长度,此外,debug object属于调试命令,运行代价较大,并且在其运行时,进入Redis的其余请求将会被阻塞直到其执行完毕。并且每次只能查找单个key的信息,官方不推荐使用。

  • 3、redis-rdb-tools开源工具

这种方式是在redis实例上执行bgsave,bgsave会触发redis的快照备份,生成rdb持久化文件,然后对dump出来的rdb文件进行分析,找到其中的大key。
GitHub地址:https://github.com/sripathikrishnan/redis-rdb-tools
优点在于获取的key信息详细、可选参数多、支持定制化需求,结果信息可选择json或csv格式,后续处理方便,其缺点是需要离线操作,获取结果时间较长。

五、如何解决Big Key问题?

要解决Big Key问题,无非就是减小key对应的value值的大小,也就是对于String数据结构的话,减少存储的字符串的长度;对于List、Hash、Set、ZSet数据结构则是减少集合中元素的个数。

  • 1、对大Key进行拆分

将一个Big Key拆分为多个key-value这样的小Key,并确保每个key的成员数量或者大小在合理范围内,然后再进行存储,通过get不同的key或者使用mget批量获取。

  • 2、对大Key进行清理

对Redis中的大Key进行清理,从Redis中删除此类数据。Redis自4.0起提供了UNLINK命令,该命令能够以非阻塞的方式缓慢逐步的清理传入的Key,通过UNLINK,你可以安全的删除大Key甚至特大Key。

  • 3、监控Redis的内存、网络带宽、超时等指标

通过监控系统并设置合理的Redis内存报警阈值来提醒我们此时可能有大Key正在产生,如:Redis内存使用率超过70%,Redis内存1小时内增长率超过20%等。

  • 4、定期清理失效数据

如果某个Key有业务不断以增量方式写入大量的数据,并且忽略了其时效性,这样会导致大量的失效数据堆积。可以通过定时任务的方式,对失效数据进行清理。

  • 5、压缩value

使用序列化、压缩算法将key的大小控制在合理范围内,但是需要注意序列化、反序列化都会带来一定的消耗。如果压缩后,value还是很大,那么可以进一步对key进行拆分。

  • 30
    点赞
  • 164
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Redis,zset是一种有序集合,它的元素是唯一的,每个元素都会关联一个权重值(score),并按照权重值进行排序。zset的大key问题是指当zset元素数量过多或者元素的权重值过大时,会导致zset成为一个大key,从而影响Redis的性能和可用性。 具体来说,zset的大key问题可能会导致以下问题: 1. 内存占用过高:当zset元素数量过多或者元素的权重值过大时,会导致zset占用大量的内存资源,从而导致Redis的内存占用过高,影响Redis的性能和稳定性。 2. 命令执行时间过长:当zset成为一个大key时,执行zset相关的命令(如zadd、zrange等)的时间会变得很长,从而导致Redis的响应时间变慢,影响用户体验。 3. 持久化时间过长:当zset成为一个大key时,进行持久化操作(如RDB或AOF)的时间会变得很长,从而影响Redis的性能和可用性。 为了解决zset的大key问题,可以采取以下措施: 1. 分散zset:将zset拆分成多个小的zset,每个zset只包含一部分元素,从而避免成为一个大key。 2. 调整zset的权重值:如果zset元素的权重值过大,可以考虑调整权重值,使它们不会影响Redis的性能和稳定性。 3. 优化命令:对于zset相关的命令,可以优化命令的执行方式,减少命令执行时间,从而提高Redis的性能和响应时间。 4. 使用zscan命令:当zset元素数量过多时,可以使用zscan命令来遍历zset,避免一次性获取全部元素,从而减少对内存的占用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值