Redis bigkey学习笔记

一、什么是Redis bigkey

下面两种情况,redis的key我们认为他是bigkey:

  • 字符串类型:在redis中一个字符串最大是512MB,所谓bigkey是指单个value很大,一般超过10KB就认为是bigkey
  • 非字符串类型:哈希、列表、集合、有序集合等集合类型,bigkey主要体现在元素个数太多

二、bigkey的危害

bigkey可以说是redis中的老鼠屎,具体表现在:

2.1、内存空间不均匀

有bigkey的redis节点占用内存多,而其他节点占用内存少,导致集群中不同redis节点的内存空间占用不均匀。

2.2、超时阻塞

由于redis是单线程,如果操作bigkey时间太久,会引起其他客户端操作阻塞。

2.3、网络拥塞

bigkey也意味着每次访问会占用较大的网络流量。例如,一个bigkey是1MB,客户端每秒访问1000次,那么每秒消耗的网络流量时1000MB,对于普通的千兆网卡(按照字节算是128MB/s)的服务器来说简直就是灭顶之灾。如果该Redis服务器是多个应用混步,会影响其他应用。

2.4、过期删除

有个bigkey, 假设他安分守己(只执行最简单的命令,例如hget, lpop, zscore等),但由于他设置了过期时间,当他过期后,就会被删除,如果没有使用Redis 4.0的过期异步删除(lazyfree-lazy-expire yes),就会存在阻塞redis的可能性。

2.5、迁移困难

当需要对bigkey进行迁移(如Redis cluster的迁移slot),是通过migrate命令来完成的。migrate命令实际上时dump + restore + del三个命令组合成原子命令来完成的,如果是bigkey,可能使迁移命令失败,而较慢的migrate命令会阻塞redis。

三、bigkey是怎样产生的

一般来说,bigkey是由于程序员的程序设计不当,或对数据规模预料不清楚造成的:
1、社交类:粉丝列表,如果某些明显或大V,一定是bigkey
2、统计类:如果按天存储某项功能或网站的用户集合,除非没几个人用,否则必定是bigkey
3、缓存类:作为数据库数据的冗余存储,这种是redis的最常用场景,但有2点要注意:
1)是不是有必要把所有数据都缓存
2)有没有相关关联的数据
举个例子,该同学把某明星一个专辑下的所有视频信息都缓存成了一个巨大的json,这个json达到了6MB。

四、如何删除bigkey

如果发现了bigkey, 确认是垃圾是不是可以直接del?
1、对于string类型,直接删除是可以的,只要删除速度不太慢。
2、对于集合类型的数据,随着元素个数的增长及每个元素字节数的增大,删除速度会越来越慢,存在阻塞redis的隐患。所以,在删除他们的时候,建议采用渐进式的方式来完成:hscan, ltrim, sscan, zscan。
当然,迁移是bigkey不那么大,即删除时间不那么长(不超过redis客户端的重试时间),才不会影响业务。

如果使用的Redis 4.0及以上版本,异步删除unlink就可以解决。

五、总结

由于开发人员对Redis的理解程度不同,在实际开发中出现bigkey在所难免,重要的是通过合理的检测机制及时找到他们,进行处理。

作为开发人员,在业务开发时不能将redis简单暴力的事宜,应该在数据结构的选择和设计上更加合理。如果出现了bigkey,要思考是否可以做一些诱惑(例如二级索引),尽量让这些key消失在业务中。如果bigkey不可避免,也要思考要不要每次把所有元素都全部取出来(有时仅需要hmget, 而不需要hgetall),删除也是一样,尽量使用优雅的方式。

你可能感兴趣的:(中间件-Redis,redis,数据库)