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

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

预分配: 明确窗口队列大小上限,在数组初始化时,预分配固定大小的空间可以消除队列运行时动态扩容的开销。
相关推荐
Lee川6 小时前
LangChain 加持:后端 AI 流式对话的优雅实现
后端
子兮曰7 小时前
Bun v1.3.14 深度解析:Image API、HTTP/3、全局虚拟存储与五十项变革
前端·后端·bun
ltl7 小时前
Self-Attention:让序列自己看自己
后端
楼兰公子7 小时前
buildroot 在编译rust时裁剪平台类型数量的方法
开发语言·后端·rust
吴声子夜歌8 小时前
Go——并发编程
开发语言·后端·golang
释怀°Believe8 小时前
Spring解析
java·后端·spring
Cosolar8 小时前
大模型应用开发面试 • 每日三题|Day 003|多Agent系统中的通信协议、冲突解决和一致性保障
人工智能·后端·面试
汪汪大队u8 小时前
续:从 Docker Compose 到 Kubernetes(2)—— 服务优化与排错
网络·后端·物联网·struts·容器
前进的李工9 小时前
MySQL慢查询日志优化实战
数据库·mysql·性能优化
天若有情6739 小时前
前端高阶性能优化:跳出传统懒加载与预加载,基于用户行为做轻量预判加载
前端·性能优化