前不久因为公司业务需要,需要解决大促场景下后端业务的热点缓存问题,于是我们研究了缓存热点的解决方案。很多公司的缓存都是基于redis的。Redis的性能其实足以应对大部分场景。但是对于某款爆款产品,在大促或者活动抢购的时候,可能会在几秒内大量涌入。由于在redis集群场景下,一个热点产品的数据会按照hash规则存储到一个redisshard中,所以这几秒的流量会压到redisshard上,导致redisshard分裂成一个立即的。分片的瘫痪也会影响后续redis请求的阻塞。另一种场景是,并非所有公司的服务器端逻辑都有缓存。当流量增加时,这些热键仍然会被推送到数据库层面。造成压力。解决方案常见的解决方案是增加二级缓存,将热点数据拷贝一份到jvm中。设置过期时间。但是什么时候设置,怎么检测热点,规则怎么设置,过期时间设置多少。甚至如何快速落地,这也是需要研究的问题。我们希望对这些问题有一个统一的解决方案。我们发现了Hotkey,一个开源框架。Hotkey源自京东。Hotkey可以根据配置的规则在毫秒级自动检测任何突发的、不可预测的热点数据。检测到的热点数据会被推送到所有服务器的JVM,大大降低了对端数据层的影响。这些热点数据会在整个微服务集群中保持一致性,当热点消失后,会自动从jvm中移除。Hotkey的功能非常适合我们的目的。此外,京东还使用Hotkey实战618促销,稳定性有保障。Hotkey的架构图(下图引用自Gitee上Hotkey的主页)。整个Hotkey架构分为以下几个部分:worker:负责收集和上报信息,并根据规则计算热点信息。规则来自etcd。向客户端推送热点信息Client:每个客户端连接etcd,获取每个worker的IP和端口,与worker保持长连接,接受worker的热点信息推送etcd:分布式协调器,接受每个worker的心跳报告,并将worker的连接信息推送给客户端。监听规则的变化,推送到workerdashboard:ui界面,查看实例和worker的状态,查看和修改规则数据。规则存储在mysql中,同时由etcd推送给worker。下面给出了hotkey的项目地址https://gitee.com/jd-platform...关于Hotkey的介绍和搭建方法,可以看这篇文章了解,这里就不赘述了。https://mp.weixin.qq.com/s/xO...遇到的问题我们在搭建hotkey环境和实现的过程中遇到了两个问题:Hotkey虽然是开源的,但是相关的客户端jar包还没有上传的中央仓库、dashboard和worker启动包不提供下载。需要下载源码进行编译,编译过程中也会遇到一些包依赖问题。Hotkey的客户端jar只提供API级别的方法供程序使用。如果要在业务项目中实现,需要进行大规模的代码修改才能实现。我们更愿意提供一种侵入性较小的方法来在RPC和接口级别执行代理包装。无论用户使用什么RPC框架,都只是在相关接口上做标记,而不会触及业务的任何代码。可以在此接口级别检测热点。如果接口的某个参数是热点,会自动代理,使用jvm的热点数据。热点消除后,仍会使用原来的通话。如果你觉得上面的描述太难理解,那就直白一点:比如在一次促销活动中,有一个商品S001正在抢购,大量的流量进入了商品详情页。这个商品详情的RPC方法调用了下面的商品服务接口方法来获取商品信息:publicinterfaceProductService{SkuInfogetSkuInfo(StringskuCode);}那我们希望只标记这个接口。它可以适配Hotkey框架来检测热点。当产品S001被大量需求时,产品S001就会成为热点。这时会自动代理getSkuInfo接口,使其只从Jvm获取数据,而不会真正离开RPC调用。热点消除后,该接口仍然调用RPC获取数据。这种方式无疑侵入性更小,更容易实现Hotkey框架。Hotlink客户端为此,我们在Hotkey客户端的基础上开发了Hotlink客户端框架。该客户端框架可以使Hotkey更加完善,增强Hotkey客户端的能力。Hotlink的项目地址:https://gitee.com/openbeast/h...这个客户端框架有以下特点:业务接入简单,只需要一个注解,1分钟就能让你的RPC接口接入热点检测时框架启动后,会动态扫描所有被Hotlink标记的接口,并创建动态代理,在动态代理的基础上对接口进行增强。理论上只要有接口,任何RPC框架本地方法都可以使用。只要有接口,热点检测也可以结合Hotkey的架构图来使用,Hotlink在整个架构图中的位置如下:如何使用Hotlink第一步是根据Hotkey的部署需求搭建worker和dashboard。具体方法可以参考:https://gitee.com/jd-platform...同时为了方便大家搭建,我也上传了编译好的worker和dashboard包。worker下载地址:公网IP版(适合调试),本地可以连接worker:https://gitee.com/openbeast/h...内网IP版:https://gitee.com/openbeast/h...dashboard:https://gitee.com/openbeast/h...第二步,本地业务项目依赖jar包(此jar包还没有上传到中央仓库,需要部署到你公司的私有仓库)
