l2cache [热key探测]技术方案调研

l2cache 源码地址

一、背景

现状

在高并发系统中,热key一直以来都是一个不可避免的问题(无法通过加机器来解决)。
由于目前核心主链路中存在突发的无法预先感知的流量,而这些热点访问会对数据层造成冲击,严重时会导致Redis的带宽满载,最终可能导致系统崩溃,影响应用层系统稳定性。所以我们需要一种手段来自动探测热点数据,期望通过它大幅降低热点数据对数据层的冲击,并提升应用性能。

目的

  1. 提升系统应对未知的突发流量的能力,提升系统稳定性和健壮性
  2. 大促时人为手动预热缓存的人力释放,同时也可避免人为操作的风险
  3. 降低数据层的压力和成本,提升应用的性能

二、技术调研

方案一:接入京东hotkey

简介

京东hotkey框架(JD-hotkey)是京东app后台研发的一款高性能热数据探测中间件,用来实时探测出系统的热数据,并将热数据毫秒内推送至系统的业务集群服务器的JVM内存。。
该框架主要用于对任意突发性的无法预先感知的热key,包括并不限于热点数据(如突发大量请求同一个商品)、热用户(如恶意爬虫刷子)、热接口(突发海量请求同一个接口)等,进行毫秒级精准探测到。然后对这些热key,推送到所有服务端JVM内存中,以大幅减轻对后端数据存储层的冲击,并可以由使用者决定如何分配、使用这些热key(譬如对热商品做本地缓存、对热用户进行拒绝访问、对热接口进行熔断或返回默认值)。这些热数据在整个服务端集群内保持一致性,并且业务隔离,worker端性能强悍。

核心功能

  • client端按key维度分组统计访问次数
  • client定时按key取模后,通过netty向worker汇报统计数据
  • worker对发来的key进行滑动窗口累加计算,达到用户设置的阈值,则将该key推送至整个业务服务器集群内
  • client端接收到到热key,将其加入到本地缓存

适用场景

  • mysql热数据本地缓存
  • redis热数据本地缓存
  • 黑名单用户本地缓存
  • 爬虫用户限流
  • 接口、用户维度限流
  • 单机接口、用户维度限流
  • 集群用户维度限流
  • 集群接口维度限流

优点

  • 完备性:功能相对完整(热key探测、可视化监控等)
  • 稳定性:京东开源且经历2020年京东618、双11大促考验
  • 性能:历经多次压测,性能有保障
    • 探测性能:8核单机worker端每秒可接收处理16万个key探测任务
    • 推送性能:对外推送目前性能约平稳推送每秒10-12万次
    • worker端每秒单机吞吐量(写入+对外推送)目前在70万左右稳定
  • 开发难度:l2cache接入京东hotkey相对简单且开发时间短

缺点

  • 不确定性:
    • 团队对京东hotkey源码了解程度低
    • 引入ETCD,而团队对ETCD缺乏了解,相对有点重
    • 官方的性能数据有待验证
  • 维护成本高:因团队对京东hotkey源码和设计理念了解程度低,问题排查难度和二次开发成本高
  • 扩展性差:京东hotkey扩展点少,当某些通用需求和业务紧密结合时京东hotkey无法满足
  • 代码质量:代码质量一般,有优化空间

案例demo

  • 秒级16万时,cpu大概25%

  • 秒级36.5万时,cpu在50%

性能数据

  1. 实例 CPU为16核
  2. 热key探测计算:每秒可接收N台服务器发来的40多万个待测key,并计算完毕其中的35万左右。实测可每秒稳定计算30万,极限计算37万,超过的量会进入队列等待。
  3. 热key推送:当热key产生后,对该业务集群所有长连接的服务器进行key推送,每秒可稳定推送10-12万次(毫秒内送达)。譬如1千台服务器,每秒该worker可以支撑产生100个热key,即推送100*1000次。当每秒产生200个热key,即每秒需要推送20万次时,会出现有1s左右的延迟送达。

方案二:阿里Sentinel热点参数限流

简介

阿里Sentinel 热点参数限流 是用于统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。基于此特性,我们可将热点参数限流看做一个热key探测功能,也就是说将被限流的热点参数看做热key,然后存放到本地缓存,变向达到热key探测的目的。

限流的直接表现是在执行 Entry nodeA = SphU.entry(资源名字) 的时候抛出 FlowException 异常。FlowException 是 BlockException 的子类,您可以捕捉 BlockException 来自定义被限流之后的处理逻辑。

适用场景

  • 热点商品探测

优点

  • 支持单机模式和集群模式的热点参数限流(探测)
  • 历经10 年双十一的丰富流量场景验证
  • 开源且社区活跃

缺点

  • 需验证可行性

方案三:自研热key探测

基本思路:

  • 基于netty实现上报访问数量(保证实时性)
  • 基于netty实现下发热key(保证高性能)
  • 基于滑动窗口实现热key统计(保证准确性)
  • 基于nacos做注册中心和配置中心

优点

  • 技术栈匹配度:自研可更好的适配公司当前的技术栈,统一技术栈
  • 可控性高:自研使团队对组件的把控程度高
  • 沉淀通用解决方案:适当造轮子,形成公司自有的一套完整的多级缓存解决方案

缺点

  • 开发难度高:
    • 对开发人员要求高,需对各种知识都有涉猎
    • 实践过程中不会一帆风顺(挑战、新事物)
    • 开发时间相对较长
  • 稳定性:
    • 自研组件的稳定性需要经过时间的洗礼和实际业务场景来进行验证
    • 对各种极端场景需要覆盖
  • 完备性:缺少可视化监控(逐步迭代)
  • 性能:需经过多次压测来保障性能

结论

基于三个方案的优缺点,前期建议采用【方案一:接入京东hotkey】,中期接入阿里Sentinel,最后根据实际情况看是否自研。

三、其他

升级l2cache

  1. l2cache新增热key探测模块。
  2. 支持扩展多种方式的热key探测实现。

热key探测关键指标

  1. 实时性:当某个key刚有热的苗头,在短时间内(500ms/1s)它就已经进到整个服务集群的内存里。
  2. 准确性:累加key的访问数量,做到不误探,保证探测出的热key完全符合自己设定的阈值。
  3. 高性能:做热key探测目的就是为了降低数据层的负载,提升应用层的性能,节省服务器资源,也就是说高性能带来的就是低成本。

四、相关文档

[京东开源热key探测(JD-hotkey)中间件单机qps 提升17倍实战]

你可能感兴趣的:(项目实战,缓存,高并发,java,jvm,开发语言)