剖析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)),因为不需要移动其他元素,通常只涉及修改头部和尾部指针以及对数组下标进行模运算。

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

预分配: 明确窗口队列大小上限,在数组初始化时,预分配固定大小的空间可以消除队列运行时动态扩容的开销。
相关推荐
bobz96513 分钟前
mcp 直接操作浏览器
后端
前端小张同学3 小时前
服务器部署 gitlab 占用空间太大怎么办,优化思路。
后端
databook3 小时前
Manim实现闪光轨迹特效
后端·python·动效
武子康3 小时前
大数据-98 Spark 从 DStream 到 Structured Streaming:Spark 实时计算的演进
大数据·后端·spark
该用户已不存在4 小时前
6个值得收藏的.NET ORM 框架
前端·后端·.net
文心快码BaiduComate4 小时前
文心快码入选2025服贸会“数智影响力”先锋案例
前端·后端·程序员
neoooo4 小时前
🌐 Cloudflare Tunnel vs ZeroTier:两个世界的内网穿透哲学
后端
涡能增压发动积4 小时前
当你不了解“异步”时请慎用“异步”——记一次生产环境故障排查之旅
后端
文心快码BaiduComate4 小时前
用Comate Zulu开发一款微信小程序
前端·后端·微信小程序
用户8356290780514 小时前
Python 删除 Excel 工作表中的空白行列
后端·python