剖析JD-hotkey,我们能从中学到什么

hotkey作为开源的京东APP后台热数据探测框架,历经多次高压压测和2020年京东618、双11大促考验。据有极高的性能,下面我们就看看从源码中,我们可以学习到哪些优秀的思想。

1. 发布/订阅模型

Client端使用发布/订阅模式的实现 EventBus 组件,将规则,worker和热key 等信息变动的的监听和实际处理逻辑进行解耦。事件的生产者和消费者彼此独立,只需发布或订阅事件即可,不需要复杂的接口调用或回调机制,据有一定的清晰度跟灵活性。并且事件使用异步处理,提升了程序的响应性能。

2. 队列缓冲

以热key的上报流程为例,整体流程如下:

  • 客户端上报 热key 的netty事件
  • worker监听到对应的事件后,将热key信息 放到 QUEUE 阻塞队列里面
  • KeyConsumer 死循环 从 QUEUE 获取数据,进行热key计算。如果统计满足规则阈值,放入 hotKeyStoreQueue 阻塞队列
  • AppServerPusher 死循环 从 hotKeyStoreQueue 获取数据,推送到客户端

可以看到每两个步骤之间都使用了生产-消费模式。并且往队列里面放东西 就结束了,没有做实际复杂的逻辑,work线程又可以接着去进行处理新来的neety IO事件,解放了work线程 ,否则work线程 可能会被被热度计算过程捆绑 导致无法及时处理新来的IO事件。

同时用一个 BlockingQueue 作为任务的缓冲区,通过缓冲区实现客户端上报热key的流量控制。当队列满时,新的任务需要等待,无法直接执行。

复制代码
RocketMQ 5.0 的任意延时消息,也是用了相同的思想进行涉及的, 所以在同一时刻延时消息过多的时候, 会因为队列处理不及时, 导致延时消息延迟执行。 
同样的还有nacos 2.x 版本的事件机制实现。

3. 双map处理累计上报数据并发问题

读写容器分离的思想。避免加锁阻塞分支执行。具体代码细节可以查看:juejin.cn/post/735345...

4. 内存优化热度统计

使用循环数组队列 计算key的热度统计,具体实现可以参考:com.jd.platform.hotkey.worker.tool.SlidingWindow。

主要优势有以下几点:

scss 复制代码
空间复用: 循环数组队列的一个主要优势在于它可以复用空间。当队列的前端元素被移除时,空间不会被浪费;而是可以用于以后在队列后端添加的新元素。

性能: 循环数组队列在入队(enqueue)和出队(dequeue)操作上都提供了常数时间复杂度(O(1)),因为不需要移动其他元素,通常只涉及修改头部和尾部指针以及对数组下标进行模运算。

内存局部性: 由于循环数组队列在数组中连续存储元素,可以充分利用缓存和内存的局部性原理。

预分配: 明确窗口队列大小上限,在数组初始化时,预分配固定大小的空间可以消除队列运行时动态扩容的开销。
相关推荐
声声codeGrandMaster2 小时前
Django之验证码功能
数据库·后端·python·django
zwjapple4 小时前
RabbitMQ的基本使用
开发语言·后端·ruby
白开水不加冰5 小时前
Spring的BeanFactory和FactoryBean的区别
java·后端·spring
John_ToDebug5 小时前
Chromium 浏览器核心生命周期剖析:从 BrowserProcess 全局管理到 Browser 窗口实例
c++·chrome·性能优化
fashia5 小时前
Java转Go日记(三十六):简单的分布式
开发语言·分布式·后端·zookeeper·golang·go
文艺倾年7 小时前
【系统架构师】2025论文《WEB系统性能优化技术》
前端·性能优化·系统架构
北漂老男孩8 小时前
JavaScript 性能优化实战指南
开发语言·javascript·性能优化
丛烨8 小时前
C++并发性能优化思路
c++·性能优化
弥鸿8 小时前
ElasticSearch性能优化
大数据·elasticsearch·性能优化
qq_2518364578 小时前
基于springboot3 VUE3 火车订票系统前后端分离项目适合新手学习的项目包含 智能客服 换乘算法
java·开发语言·spring boot·后端·学习