一、什么是热Key?
在Redis中,我们把访问频率高的Key,称为热Key。比如突然又几十万的请求去访问redis中某个特定的Key,那么这样会造成redis服务器短时间流量过于集中,很可能导致redis的服务器宕机。那么接下来对这个Key的请求,都会直接请求到我们的后端数据库中,数据库性能本来就不高,这样就可能直接压垮数据库,进而导致后端服务不可用。
二、热Key产生的原因?
- 1、用户消费的数据远大于生产的数据,如商品秒杀、热点新闻、热点评论等读多写少的场景。
双十一秒杀商品,短时间内某个爆款商品可能被点击/购买上百万次,或者某条爆炸性新闻等被大量浏览,此时会造成一个较大的请求Redis量,这种情况下就会造成热点Key问题。
- 2、请求分片集中,超过单台Redis服务器的性能极限。
在服务端读数据进行访问时,往往会对数据进行分片切分,例如采用固定Hash分片,根据hash算法,同一个key的请求还是会落到同一台新机器上,如果瞬间访问量过大,超过机器瓶颈时,就会导致热点 Key 问题的产生。
三、热key探测
-
集群中每个slot的qps监控
热key最明显的影响,是在整个redis集群中的qps并没有那么大的前提下,流量分布在集群中slot不均的问题,那么我们可以最先想到的就是对于每个slot中的流量做监控,上报之后做每个slot的流量对比,就能在热key出现时发现影响到的具体slot。
虽然这个监控最为方便,但是粒度过于粗了,仅适用于前期集群监控方案,并不适用于精准探测到热key的场景。
-
proxy的代理机制作为整个流量入口统计
如果我们使用的是图2的redis集群proxy代理模式,由于所有的请求都会先到proxy再到具体的slot节点,那么这个热点key的探测统计就可以放在proxy中做,在proxy中基于时间滑动窗口,对每个key做计数,然后统计出超出对应阈值的key。为了防止过多冗余的统计,还可以设定一些规则,仅统计对应前缀和类型的key。
这种方式需要至少有proxy的代理机制,对于redis架构有要求。
-
redis基于LFU的热点key发现机制
redis 4.0以上的版本支持了每个节点上的基于LFU的热点key发现机制,使用redis-cli –hotkeys即可,执行redis-cli时加上–hotkeys选项。可以定时在节点中使用该命令来发现对应热点key。
这个命令的执行时间较长,可以设置定时执行来统计。
-
基于Redis客户端做探测
由于redis的命令每次都是从客户端发出,基于此我们可以在redis client的一些代码处进行统计计数,每个client做基于时间滑动窗口的统计,超过一定的阈值之后上报至server。(修改我们的业务代码,在操作redis之前,加入Key使用次数的统计逻辑,定时把收集到的数据上报到统一的服务进行聚合计算,这样我们就可以找到那些热点Key。
缺点就是对我们的业务代码有一定的侵入性。
)
四、如何解决热Key问题?
对特定key或slot做限流
一种最简单粗暴的方式,对于特定的slot或者热key做限流,这个方案明显对于业务来说是有损的,所以建议只用在出现线上问题,需要止损的时候进行特定的限流。
数据预热
数据预热即在高并发访问之前,将热点数据提前加载进缓存。例如,在每日业务高峰期开始前,提前向缓存加载热点 Key。
使用二级(本地)缓存
本地缓存也是一个最常用的解决方案,既然我们的一级缓存扛不住这么大的压力,就再加一个二级缓存吧。由于每个请求都是由service发出的,这个二级缓存加在service端是再合适不过了,因此可以在服务端每次获取到对应热key时,使用本地缓存存储一份,等本地缓存过期后再重新请求,降低redis集群压力。
拆key
如何既能保证不出现热key问题,又能尽量的保证数据一致性呢?拆key也是一个好的解决方案。
我们在放入缓存时就将对应业务的缓存key拆分成多个不同的key。如下图所示,我们首先在更新缓存的一侧,将key拆成N份,比如一个key名字叫做"good_100",那我们就可以把它拆成四份,“good_100_copy1”、“good_100_copy2”、“good_100_copy3”、“good_100_copy4”,每次更新和新增时都需要去改动这N个key,这一步就是拆key。
对于service端来讲,我们就需要想办法尽量将自己访问的流量足够的均匀,如何给自己即将访问的热key上加入后缀。几种办法,根据本机的ip或mac地址做hash,之后的值与拆key的数量做取余,最终决定拼接成什么样的key后缀,从而打到哪台机器上;服务启动时的一个随机数对拆key的数量做取余。
其他可以提前做的预案
上面的每一个方案都相对独立的去解决热key问题,那么如果我们真的在面临业务诉求时,其实会有很长的时间来考虑整体的方案设计。一些极端的秒杀场景带来的热key问题,如果我们预算充足,可以直接做服务的业务隔离、redis缓存集群的隔离,避免影响到正常业务的同时,也会可以临时采取更好的容灾、限流措施。
一些整合的方案
目前市面上已经有了不少关于hotKey相对完整的应用级解决方案,其中京东在这方面有开源的hotkey工具,原理就是在client端做洞察,然后上报对应hotkey,server端检测到后,将对应hotkey下发到对应服务端做本地缓存,并且这个本地缓存在远程对应的key更新后,会同步更新,已经是目前较为成熟的自动探测热key、分布式一致性缓存解决方案
「真诚赞赏,手留余香」
真诚赞赏,手留余香
使用微信扫描二维码完成支付
