redis的hotkey和大key

10 分钟阅读 1087 字 + 1270 词
在拥有大量并发用户的系统中,HotKey一直以来都是一个不可避免的问题。
  • 比如秒杀活动、热点微博、热评,某件商品被数万次点击浏览或购买时,就会造成热点问题
  • 比如大量发布、浏览的热点新闻、热点评论等读多写少场景也会产生热点问题
  • 比如是 瞬间大量开启的爬虫用户,
  • 突发大批机器人 以远超正常用户的速度发起极其密集的请求,这些机器人只需要很小的代价,就能发出百倍于普通用户的请求量,从而大幅挤占正常用户的资源。
以京东为例的这些头部互联网公司,动辄某个爆品,会瞬间引入每秒上百万甚至数百万的请求,当然流量多数会在几秒内就消失。
但就是这短短的几秒的HotKey,就会瞬间造成其所在redis分片集群瘫痪。
原因也很简单, redis作为一个单线程的结构,所有的请求到来后都会去排队,当请求量远大于自身处理能力时,后面的请求会陷入等待、超时。
由于该redis分片完全被这个key的请求给打满,导致该分片上所有其他数据操作都无法继续提供服务, 也就是HotKey不仅仅影响自己,还会影响和它合租的数据。
这样,redis 缓存没有响应之后,相当于 redis 击穿, 请求直接转向DB
DB的吞吐量,比如会低很多,DB 就会雪崩。
带来的问题
  • HotKey占用大量的Redis CPU时间,使其性能变差并影响其它请求;
  • Redis Cluster中各node流量不均衡造成Redis Cluster的分布式优势无法被Client利用,一个分片负载很高而其它分片十分空闲从而产生读/写热点问题;
  • 在抢购、秒杀活动中,由于商品对应库存Key的请求量过大,超出Redis处理能力造成超卖;
  • HotKey的请求压力数量超出Redis的承受能力造成缓存击穿,此时大量请求将直接指向后端存储,将后端存储打挂并影响到其它业务;
  • 流量过于集中,突破物理网卡的极限
  • 请求过多,缓存分片服务被打垮
  • 穿透DB
解决方法
1.在 应用层引入本地缓存(如Guava Cache、Caffeine、nginx share dict等) ,将热点数据缓存在本地内存中,减少对Redis的直接访问,从而降低Redis的压力。
**优点:**减少了对Redis的读请求,降低了热点Key带来的负载压力。
2.通过 改变Key的结构(如添加随机前缀),将同一个热点Key拆分成多个Key,使其分布在不同的Redis节点上 ,从而避免所有流量集中在一个节点上,访问的时候可以访问多个key。
**优点:**有效避免了单点瓶颈,提高了Redis集群的整体吞吐量。
如果是用 : redis 主从架构,可以通过增加Redis集群中的从节点,增加 多个读的副本。
3.通过对 读流量进行 负载均衡 , 将读流量 分散到更多的从节点 上,减轻单个节点的压力。
优点 :通过水平扩展,Redis可以处理更大的负载,特别是针对高并发的读请求。
4.实现一个redis代理,结合两个功能: 热点数据发现,然后存在本地缓存。
一些问题
image-20241118152359276
image-20241118152409905
image-20241118152611028
拆分 大Key 的解决原理
将一个大 Key 按规则分解为多个小 Key,实现:
  • 负载分散 :小 Key 分布在多个节点(如 Redis Cluster 分片)。
  • 并行处理 :单一操作变多线程/多节点协同。
  • 精准读写 :按需访问子 Key,减少数据传输量。
image-20241118153447662
image-20241118153524686
image-20241118153847627
image-20241118153830944
image-20241118153950018
image-20241118154110630