Redis的热key解决

1、Redis热Key会带来哪些问题

1、流量集中,达到物理网卡上限。

当某一热点 Key 的请求在某一主机上超过该主机网卡上限时,由于流量的过度集中,会导致服务器中其它服务无法进行。

2、请求过多,缓存分片服务被打垮。

如果热点过于集中,热点 Key 的缓存过多,超过目前的缓存容量时,就会导致缓存分片服务被打垮现象的产生。

3、DB 击穿,引起业务雪崩。

当缓存服务崩溃后,此时再有请求产生,会缓存到后台 DB 上,由于DB 本身性能较弱,在面临大请求时很容易发生请求穿透现象,会进一步导致雪崩现象,严重影响设备的性能。

二、如何解决热Key问题

目前业内的方案有两种 (1)利用二级缓存 比如利用ehcache,或者一个HashMap都可以。在你发现热key以后,把热key加载到系统的JVM中。 针对这种热key请求,会直接从jvm中取,而不会走到redis层。 假设此时有十万个针对同一个key的请求过来,如果没有本地缓存,这十万个请求就直接怼到同一台redis上了。 现在假设,你的应用层有50台机器,OK,你也有jvm缓存了。这十万个请求平均分散开来,每个机器有2000个请求,会从JVM中取到value值,然后返回数据。避免了十万个请求怼到同一台redis上的情形。 (2)备份热key 这个方案也很简单。不要让key走到同一台redis上不就行了。我们把这个key,在多个redis上都存一份不就好了。接下来,有热key请求进来的时候,我们就在有备份的redis上随机选取一台,进行访问取值,返回数据。 假设redis的集群数量为N,步骤如下图所示

注:不一定是2N,你想取3N,4N都可以,看要求。 伪代码如下

复制代码
constM = N * 2
//生成随机数
random = GenRandom(0, M)
//构造备份新key
    bakHotKey = hotKey + “_” + randomdata = redis.GET(bakHotKey)ifdata == NULL {
    data = GetFromDB()
    redis.SET(bakHotKey, expireTime + GenRandom(0,5))
}

业内方案

OK,其实看完上面的内容,大家可能会有一个疑问。

烟哥,有办法在项目运行过程中,自动发现热key,然后程序自动处理么?

嗯,好问题,那我们来讲讲业内怎么做的。其实只有两步 (1)监控热key (2)通知系统做处理 正巧,前几天有赞出了一篇《有赞透明多级缓存解决方案(TMC)》,里头也有提到热点key问题,我们刚好借此说明 (1)监控热key 在监控热key方面,有赞用的是方式二:在客户端进行收集。 在《有赞透明多级缓存解决方案(TMC)》中有一句话提到

TMC 对原生jedis包的JedisPool和Jedis类做了改造,在JedisPool初始化过程中集成TMC"热点发现"+"本地缓存"功能Hermes-SDK包的初始化逻辑。

也就说人家改写了jedis原生的jar包,加入了Hermes-SDK包。 那Hermes-SDK包用来干嘛? OK,就是做热点发现本地缓存。 从监控的角度看,该包对于Jedis-Client的每次key值访问请求,Hermes-SDK 都会通过其通信模块将key访问事件异步上报给Hermes服务端集群,以便其根据上报数据进行"热点探测"。

当然,这只是其中一种方式,有的公司在监控方面用的是方式五:自己抓包评估。 具体是这么做的,先利用flink搭建一套流式计算系统。然后自己写一个抓包程序抓redis监听端口的数据,抓到数据后往kafka里丢。 接下来,流式计算系统消费kafka里的数据,进行数据统计即可,也能达到监控热key的目的。

(2)通知系统做处理 在这个角度,有赞用的是上面的解决方案一:利用二级缓存进行处理。 有赞在监控到热key后,Hermes服务端集群会通过各种手段通知各业务系统里的Hermes-SDK,告诉他们:"老弟,这个key是热key,记得做本地缓存。" 于是Hermes-SDK就会将该key缓存在本地,对于后面的请求。Hermes-SDK发现这个是一个热key,直接从本地中拿,而不会去访问集群。

除了这种通知方式以外。我们也可以这么做,比如你的流式计算系统监控到热key了,往zookeeper里头的某个节点里写。然后你的业务系统监听该节点,发现节点数据变化了,就代表发现热key。最后往本地缓存里写,也是可以的。

通知方式各种各样,大家可以自由发挥。本文只是提供一个思路。

参考文献:

https://www.cnblogs.com/rjzheng/p/10874537.html

https://juejin.cn/post/7010231093664153613

Redis 热 Key 发现以及解决办法 | 董宗磊的博客--靡不有初,鲜克有终

相关推荐
minihuabei1 小时前
linux centos 安装redis
linux·redis·centos
monkey_meng4 小时前
【Rust中多线程同步机制】
开发语言·redis·后端·rust
hlsd#4 小时前
go 集成go-redis 缓存操作
redis·缓存·golang
奶糖趣多多6 小时前
Redis知识点
数据库·redis·缓存
CoderIsArt7 小时前
Redis的三种模式:主从模式,哨兵与集群模式
数据库·redis·缓存
ketil2711 小时前
Redis - String 字符串
数据库·redis·缓存
王佑辉14 小时前
【redis】延迟双删策略
redis
生命几十年3万天14 小时前
redis时间优化
数据库·redis·缓存
Shenqi Lotus15 小时前
Redis-“自动分片、一定程度的高可用性”(sharding水平拆分、failover故障转移)特性(Sentinel、Cluster)
redis·sentinel·cluster·failover·sharding·自动分片·水平拆分
YMY哈19 小时前
Redis常见面试题(二)
redis