关于redis:Bigkey问题的解决思路与方式探索

作者:vivo 互联网数据库团队- Du Ting

在Redis运维过程中,因为Bigkey 的存在,会影响业务程序的响应速度,重大的还会造成可用性损失,DBA也始终和业务开发方强调 Bigkey 的躲避办法以及危害。

一、背景

在Redis运维过程中,因为Bigkey的存在,会影响业务程序的响应速度,重大的还会造成可用性损失,DBA也始终和业务开发方强调 Bigkey 的躲避办法以及危害,然而Bigkey始终没有完全避免。全网Redis集群有2200个以上,实例数量达到4.5万以上,在以后阶段进行一次全网 Bigkey查看,预计须要以年为工夫单位,十分耗时。咱们须要新的思路去解决Bigkey问题。

二、Bigkey 介绍

2.1、什么是 Bigkey

在Redis中,一个字符串类型最大能够到512MB,一个二级数据结构(比方hash、list、set、zset等)能够存储大概40亿个(2^32-1)个元素,但实际上不会达到这么大的值,个别状况下如果达到上面的状况,就能够认为它是Bigkey了。

  • 【字符串类型】: 单个string类型的value值超过1MB,就能够认为是Bigkey。
  • 【非字符串类型】:哈希、列表、汇合、有序汇合等, 它们的元素个数超过2000个,就能够认为是Bigkey。

2.2 Bigkey是怎么产生的

咱们遇到的Bigkey个别都是因为程序设计不当或者对于数据规模意料不分明造成的,比方以下的状况。

  • 【统计】:遇到一个统计类的key,是记录某网站的拜访用户的IP,随着工夫的推移,网站拜访的用户越来越多,这个key的元素数量也会越来越大,造成Bigkey。
  • 【缓存】: 缓存类key个别是这样的逻辑,将数据从数据库查问进去序列化放到Redis里,如果业务程序从Redis没有拜访到,就会查询数据库并将查问到的数据追加到Redis缓存中,短时间内会缓存大量的数据到Redis的key中,造成Bigkey。
  • 【队列】:把Redis当做队列应用,解决工作,如果生产呈现不及时状况,将导致队列越来越大,造成Bigkey。

这三种状况,都是咱们理论运维中遇到的,须要审慎应用,正当优化。

2.3 Bigkey 的危害

咱们在运维中,遇到Bigkey的状况下,会导致一些问题,会触发监控报警,重大的还会影响Redis实例可用性,进而影响业务可用性,在须要程度扩容时候,可能导致程度扩容失败。

2.3.1内存空间不平均

内存空间不平均会不利于集群对内存的对立治理,有数据失落危险。下图中的三个节点是同属于一个集群,它们的key的数量比拟靠近,但内存容量相差比拟多,存在Bigkey的实例占用的内存多了4G以上了。

能够应用应用Daas平台“工具集-操作项治理”,抉择对应的slave实例执行剖析,找出具体的Bigkey。

2.3.2 超时阻塞

Redis是单线程工作的,艰深点讲就是同一时间只能解决一个Redis的拜访命令,操作Bigkey的命令通常比拟耗时,这段时间Redis不能解决其余命令,其余命令只能阻塞期待,这样会造成客户端阻塞,导致客户端拜访超时,更重大的会造成master-slave的故障切换。造成阻塞的操作不仅仅是业务程序的拜访,还有key的主动过期的删除、del删除命令,对于Bigkey,这些操作也须要审慎应用。

超时阻塞案例

咱们遇到一个这样超时阻塞的案例,业务方反映程序拜访Redis集群呈现超时景象,hkeys拜访Redis的均匀响应工夫在200毫秒左右,最大响应工夫达到了500毫秒以上,如下图。

hkeys是获取所有哈希表中的字段的命令,剖析应该是集群中某些实例存在hash类型的Bigkey,导致hkeys命令执行工夫过长,产生了阻塞景象。

1.应用Daas平台“服务监控-数据库实例监控”,抉择master节点,抉择Redis响应工夫监控指标“redis.instance.latency.max”,如下图所示,从监控图中咱们能够看到

(1)失常状况下,该实例的响应工夫在0.1毫秒左右。

(2)监控指标下面有很多突刺,该实例的响应工夫到了70毫秒左右,最大到了100毫秒左右,这种状况就是该实例会有100毫秒都在解决Bigkey的拜访命令,不能解决其余命令。

通过查看监控指标,验证了咱们剖析是正确的,是这些监控指标的突刺造成了hkeys命令的响应工夫比拟大,咱们找到了具体的master实例,而后应用master实例的slave去剖析下Bigkey状况。

2.应用Daas平台“工具集-操作项治理”,抉择slave实例执行剖析,剖析后果如下图,有一个hash类型key有12102218个fields。

3. 和业务沟通,这个Bigkey是间断寄存了30天的业务数据了,倡议依据二次hash形式拆分成多个key,也可把30天的数据依据分钟级别拆分成多个key,把每个key的元素数量管制在5000以内,目前业务正在排期优化中。优化后,监控指标的响应工夫的突刺就会隐没了。

2.3.3 网络阻塞

Bigkey的value比拟大,也意味着每次获取要产生的网络流量较大,假如一个Bigkey为10MB,客户端每秒访问量为100,那么每秒产生1000MB的流量,对于一般的千兆网卡(依照字节算是128MB/s)的服务器来说几乎是灭顶之灾。而且咱们当初的Redis服务器是采纳单机多实例的形式来部署Redis实例的,也就是说一个Bigkey可能会对同一个服务器上的其余Redis集群实例造成影响,影响到其余的业务。

2.3.4 迁徙艰难

咱们在运维中常常做的变更操作是程度扩容,就是减少Redis集群的节点数量来达到扩容的目标,这个程度扩容操作就会波及到key的迁徙,把原实例上的key迁徙到新扩容的实例上。当要对key进行迁徙时,是通过migrate命令来实现的,migrate实际上是通过dump + restore + del三个命令组合成原子命令实现,它在执行的时候会阻塞进行迁徙的两个实例,直到以下任意后果产生才会开释:迁徙胜利,迁徙失败,期待超时。如果key的迁徙过程中遇到Bigkey,会长工夫阻塞进行迁徙的两个实例,可能造成客户端阻塞,导致客户端拜访超时;也可能迁徙工夫太长,造成迁徙超时导致迁徙失败,程度扩容失败。

迁徙失败案例

咱们也遇到过一些因为Bigkey扩容迁徙失败的案例,如下图所示,是一个Redis集群程度扩容的工单,须要进行key的迁徙,当工单执行到60%的时候,迁徙失败了。

1. 进入工单找到失败的实例,应用失败实例的slave节点,在Daas平台的“工具集-操作项治理”进行Bigkey剖析。

2. 通过剖析找出了hash类型的Bigkey有8421874个fields,正是这个Bigkey导致迁徙工夫太长,超过了迁徙工夫限度,导致工单失败了。

3.和业务沟通,这些key是记录用户拜访零碎的某个功能模块的ip地址的,拜访该功能模块的所有ip都会记录到给key外面,随着工夫的积攒,这个key变的越来越大。同样是采纳拆分的形式进行优化,能够思考依照工夫日期维度来拆分,就是一段时间段的拜访ip记录到一个key中。

4.Bigkey优化后,扩容的工单能够重试,实现集群扩容操作。

三、Bigkey的发现

Bigkey首先须要重源头治理,避免Bigkey的产生;其次是须要可能及时的发现,发现后及时处理。剖析Bigkey的办法不少,这里介绍两种比拟罕用的办法,也是Daas平台剖析Bigkey应用的两种形式,别离是Bigkeys命令分析法、RDB文件分析法。

3.1 scan命令剖析

Redis4.0及以上版本提供了–Bigkeys命令,能够剖析出实例中每种数据结构的top 1的Bigkey,同时给出了每种数据类型的键值个数以及均匀大小。执行–Bigkeys命令时候须要留神以下几点:

  • 倡议在slave节点执行,因为–Bigkeys也是通过scan实现的,可能会对节点造成阻塞。
  • 倡议在节点本机执行,这样能够缩小网络开销。
  • 如果没有从节点,能够应用–i参数,例如(–i 0.1 代表100毫秒执行一次)。
  • –Bigkeys只能计算每种数据结构的top1,如果有些数据结构有比拟多的Bigkey,是查找不进去的。

Daas平台集成了基于原生–Bigkeys代码实现的查问Bigkey的形式,这个形式的毛病是只能计算每种数据结构的top1,如果有些数据结构有比拟多的Bigkey,是查找不进去的。该形式绝对比拟平安,曾经凋谢进去给业务开发同学应用。

3.2 RDB文件剖析

借助开源的工具,比方rdb-tools,剖析Redis实例的RDB文件,找出其中的Bigkey,这种形式须要生成RDB文件,须要留神以下几点:

  • 倡议在slave节点执行,因为生成RDB文件会影响节点性能。
  • 须要生成RDB文件,会影响节点性能,尽管在slave节点执行,然而也是有可能造成主从中断,进而影响到master节点。

Daas平台集成了基于RDB文件剖析代码实现的查问Bigkey的形式,能够依据理论需要自定义填写N,剖析的top N个Bigkey。该形式绝对有肯定危险,只有DBA有权限执行剖析。

3.3 Bigkey 巡检

通过巡检,能够暴露出隐患,提前解决,防止故障的产生,进行全网Bigkey的巡检,是防止Bigkey故障的比拟好的办法。因为全网Redis实例数量十分大,剖析的速度比较慢,应用以后的分析方法很难实现。为了解决这个问题,存储研发组分布式数据库同学打算开发一个高效的RDB解析工具,而后通过大规模解析RDB文件来剖析Bigkey,能够进步剖析速度,实现Bigkey的巡检。

四、 Bigkey解决优化

4.1 Bigkey拆分

优化Bigkey的准则就是string缩小字符串长度,list、hash、set、zset等缩小元素数量。当咱们晓得哪些key是Bigkey时,能够把单个key拆分成多个key,比方以下拆分形式能够参考。

  • big list:list1、list2、…listN
  • big hash:能够做二次的hash,例如hash%100
  • 依照日期拆分多个:key20220310、key20220311、key202203212

4.2 Bigkey剖析工具优化

咱们全网Redis集群有2200以上,实例数量达到4.5万以上,有的比拟大的集群的实例数量达到了1000以上,后面提到的两种Bigkey剖析工具还都是实例维度剖析,对于实例数量比拟大的集群,进行全集群剖析也是比拟耗时的,为了进步剖析效率,从以下几个方面进行优化:

  • 能够从集群维度抉择全副slave进行剖析。
  • 同一个集群的雷同服务器slave实例串行剖析,不同服务器的slave实例并行剖析,最大并发度默认10,同时能够剖析10个实例,并且能够自定义输出执行剖析的并发度。
  • 剖析出合乎Bigkey规定规范的所有key信息:大于1MB的string类型的所有key,如果不存在就列出最大的50个key;hash、list、set、zset等类型元素个数大于2000的所有key,如不存在就给出每种类型最大的50个key。
  • 减少暂停、从新开始、完结性能,暂停剖析后能够从新开始。

4.3 程度扩容迁徙优化

目前状况,咱们有一些Bigkey的发现是被动的,一些是在程度扩容时候发现的,因为Bigkey的存在导致扩容失败了,重大的还触发了master-slave的故障切换,这个时候可能曾经造成业务程序拜访超时,导致了可用性降落。

咱们剖析了Daas平台的程度扩容时迁徙key的过程及影响参数,内容如下:

(1)【cluster-node-timeout】:管制集群的节点切换参数,master梗塞超过cluster-node-timeout/2这个工夫,就会主观断定该节点下线pfail状态,如果迁徙Bigkey阻塞工夫超过cluster-node-timeout/2,就可能会导致master-slave产生切换。

(2)【migrate timeout】:管制迁徙io的超时工夫,超过这个工夫迁徙没有实现,迁徙就会中断。

(3)【迁徙重试周期】:迁徙的重试周期是由程度扩容的节点数决定的,比方一个集群扩容10个节点,迁徙失败后的重试周期就是10次。

(4)【一个迁徙重试周期内的重试次数】:在一个起迁徙重试周期内,会有3次重试迁徙,每一次的migrate timeout的工夫别离是10秒、20秒、30秒,每次重试之间无距离。

比方一个集群扩容10个节点,迁徙时候遇到一个Bigkey,第一次迁徙的migrate timeout是10秒,10秒后没有实现迁徙,就会设置migrate timeout为20秒重试,如果再次失败,会设置migrate timeout为30秒重试,如果还是失败,程序会迁徙其余新9个的节点,然而每次在迁徙其余新的节点之前还会别离设置migrate timeout为10秒、20秒、30秒重试迁徙那个迁徙失败的Bigkey。这个重试过程,每个重试周期阻塞(10+20+30)秒,会重试10个周期,共阻塞600秒。其实前面的9个重试周期都是无用的,每次重试之间没有距离,会间断阻塞了Redis实例。

(5)【迁徙失败日志】:迁徙失败后,记录的日志没有包含迁徙节点、solt、key信息,不能依据日志立刻定位到问题key。

咱们对这个迁徙过程做了优化,具体如下:

(1)【cluster-node-timeout】:默认是60秒,在迁徙之前设置为15分钟,避免因为迁徙Bigkey阻塞导致master-slave故障切换。

(2)【migrate timeout】:为了最大限度缩小实例阻塞工夫,每次重试的超时工夫都是10秒,3次重试之间距离30秒,这样最多只会间断阻塞Redis实例10秒。

(3)【重试次数】:迁徙失败后,只重试3次(重试是为了防止网络抖动等起因造成的迁徙失败),每次重试距离30秒,重试3次后都失败了,会暂停迁徙,日志记录下Bigkey,去掉了其余节点迁徙的重试。

(4)【优化日志记录】:迁徙失败日志记录迁徙节点、solt、key信息,能够立刻定位到问题节点及key。

五、总结

本文通过对Bigkey的剖析,重点介绍了在运维中对bigkey问题的解决思路、解决形式。首先是须要从源头治理,避免Bigkey造成,DBA应该增强对业务开发同学bigkey相干问题的宣导;其次是须要具备及时发现的能力,这个也是咱们当初的不足之处。咱们前面会从Bigkey巡检、Bigkey剖析工具的这两个方面,进步Bigkey发现能力。

参考资料:

  1. Redis命令参考
  2. Github:rdb-tools
  3. redis之bigkey(看这一篇就够)

【腾讯云】轻量 2核2G4M,首年65元

阿里云限时活动-云数据库 RDS MySQL  1核2G配置 1.88/月 速抢

本文由乐趣区整理发布,转载请注明出处,谢谢。

您可能还喜欢...

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据