Redis学习系列之—— JDHotKey 热点缓存探测系统
一、为什么需要热点缓存探测
在回答这个问题前,我们先考虑一下:为什么光用 Redis 还不够,还需要使用本地缓存?
一般来说,Redis 集群的性能能抗住几十万并发,能够应付大部分情况。但对于一些头部 APP,当出现热点舆情、商品秒杀活动等百万并发的场景,Redis 集群也来不及处理这么多请求,更何况对某一个热点 key 的请求会打到同一个 Redis 分片上。这会导致 Redis 服务超时甚至不可用,最终形成缓存雪崩。
如果能把热点数据缓存到应用程序节点中,就可以解决问题,因为本地缓存有以下优势:
1、数据不需要通过网络传输,能提升性能
2、由于应用的高扩展性,本地缓存是天然的分布式存储,负载分担容易实现
3、本地缓存可以缓解远程缓存的压力
但是,使用本地缓存最重要的问题是:本地内存有限,无法支持大量数据存储
因此在超高并发业务下,需要引入热点缓存探测系统(以下简称“热点系统”),它解决本地缓存问题的方法大致如下:
由于本地内存有限,所以最好是只存储热点数据,从而兼顾内存规模和缓存命中率。但是超高并发业务往往采用大量的应用节点,每个节点分担到的流量有限,所以单个节点仅分析自身的数据使用情况,难以及时得知哪些是热点 key。而热点系统把各节点的数据使用情况进行收集、汇总,从全局判断出哪些属于热点 key,再把热点 key 推送给各应用节点。
二、热点 key 的使用场景
热点数据有两个重要特性:有限时间、流量高聚。热点 key 的使用场景主要有:
1、正面的:例如热门商品的 id、热点舆情的 id。这些 key 作为热点 key 后,数据缓存到本地,商品详情、舆情详情等信息就不用再从 Redis 获取了,减小了 Redis 压力。
2、负面的:例如使用抢票脚本的 ip 地址。这些 key 作为热点 key 后,数据缓存到本地,当请求到来后,直接从本地缓存看一下是否存在,若存在就拒绝这些请求。
当然,热点系统只是把 key 当作一个字符串,具体在什么场景使用,非常灵活。
三、JDHotKey 架构剖析
(一)整体架构
JDHotKey 主要由 4 个组件构成:
1、etcd:etcd 是一个高性能的配置中心,可以以极小的资源占用,提供高效的监听订阅服务。主要用于存放规则配置,各 worker 的 ip 地址,以及探测出的热 key、手工添加的热 key 等。
2、client:client 是在应用中添加的引用 jar,引入后,就可以以便捷的方式去判断某 key 是否热key。同时,该 jar 完成了 key 上报、监听 etcd 里的 rule 变化、worker 信息变化、热 key 变化,对热 key 进行本地 caffeine 缓存等。
3、worker:worker 端是一个独立部署的 Java 程序,通常部署多台根据 key 的 Hash 值进行流量分担。worker 启动后会连接 etcd,并定期上报自己的ip信息,供client端获取地址并进行长连接。之后,对各个client发来的待测key进行累加计算,当达到etcd里设定的rule阈值后,将热key推送到各个client。
4、dashboard:dashboard 是一个可视化控制台,启动后会连接 etcd,之后在控制台设置各个 APP 的 key 规则。然后当worker探测出来热key后,会将 key 发往 etcd,dashboard 也会监听热 key 信息,进行入库保存记录。同时,dashboard 也可以手工添加、删除热 key,供各个 client 端监听。
(二)核心业务逻辑
1、规则维护:主要由运营人员通过 dashboard 配置热点规则,比如:对于所有 product 开头的 key,2秒内出现20次访问算热 key)。
2、热点上报:client 端会根据热点规则,将参与热点统计的 key 进行本地统计,并定期(默认 500 ms 一次)上报给 worker。上报时,会对 key 进行 hash 运算后取余,找到对应的 worker 进行上报。
3、热点统计:每个 worker 会负责自己管辖范围内的 key 的统计,采用的是滑动窗口算法。
4、热点推送:当 worker 热点统计发现热 key 时,将热 key 推送给所有的 client。此外,dashboard 也可以手动添加或删除热 key 并进行推送。
5、热点缓存:当 client 收到热点推送后,会从本地的热 key 集合中进行添加或删除。开发人员可以通过 client 提供的 SDK 查询某个 key 是否为热 key,也可以通过 SDK 从本地缓存(Caffiene)中存入、获取、删除热 key 对应的 value。
参考:https://mp.weixin.qq.com/s/xOzEj5HtCeh_ezHDPHw6Jw