高性能队列——Disruptor

应用背景和介绍

  • Disruptor 是英国外汇交易公司 LMAX 开发的一个高性能队列,研发的初衷是 解决内部的内存队列的延迟问题,而不是分布式队列。基于 Disruptor 开发的系 统单线程能支撑每秒 600 万订单,2010 年在 QCon 演讲后,获得了业界关注。
  • 据目前资料显示:应用 Disruptor 的知名项目有如下的一些:Storm,Camel, Log4j2,还有目前的美团点评技术团队也有很多不少的应用,或者说有一些借鉴了 它的设计机制。
  • Disruptor 是一个高性能的线程间异步通信的框架,即在同一个 JVM 进程中 的多线程间消息传递。

传统队列问题

在 JDK 中,Java 内部的队列 BlockQueue 的各种实现,仔细分析可以得知, 队列的底层数据结构一般分成三种:数组、链表和堆,堆这里是为了实现带有优 先级特性的队列暂且不考虑。

在稳定性和性能要求特别高的系统中,为了防止生产者速度过快,导致内存 溢出,只能选择有界队列;同时,为了减少 Java 的垃圾回收对系统性能的影响, 会尽量选择 Array 格式的数据结构。这样筛选下来,符合条件的队列就只有 ArrayBlockingQueue。但是 ArrayBlockingQueue 是通过加锁的方式保证线程安全, 而且 ArrayBlockingQueue 还存在伪共享问题,这两个问题严重影响了性能。

ArrayBlockingQueue 的这个伪共享问题存在于哪里呢,分析下核心的部分源 码,其中最核心的三个成员变量为
在这里插入图片描述
是在 ArrayBlockingQueue 的核心 enqueue 和 dequeue 方法中经常会用到的,这三 个变量很容易放到同一个缓存行中,进而产生伪共享问题。

高性能的原理

引入环形的数组结构:数组元素不会被回收,避免频繁的 GC, 无锁的设计:采用 CAS 无锁方式,保证线程的安全性 属性填充:通过添加额外的无用信息,避免伪共享问题 环形数组结构是整个 Disruptor 的核心所在。

在这里插入图片描述

首先因为是数组,所以要比链表快,而且根据我们对上面缓存行的解释知道, 数组中的一个元素加载,相邻的数组元素也是会被预加载的,因此在这样的结构 中,cpu 无需时不时去主存加载数组中的下一个元素。而且,你可以为数组预先 分配内存,使得数组对象一直存在(除非程序终止)。这就意味着不需要花大量 的时间用于垃圾回收。此外,不像链表那样,需要为每一个添加到其上面的对象 创造节点对象—对应的,当删除节点时,需要执行相应的内存清理操作。环形数 组中的元素采用覆盖方式,避免了 jvm 的 GC。

其次结构作为环形,数组的大小为 2 的 n 次方,这样元素定位可以通过位运 算效率会更高,这个跟一致性哈希中的环形策略有点像。在 disruptor 中,这个 牛逼的环形结构就是 RingBuffer,既然是数组,那么就有大小,而且这个大小必 须是 2 的 n 次方

其实质只是一个普通的数组,只是当放置数据填充满队列(即到达 2^n-1 位 置)之后,再填充数据,就会从 0 开始,覆盖之前的数据,于是就相当于一个环。

每个生产者首先通过 CAS 竞争获取可以写的空间,然后再进行慢慢往里放数 据,如果正好这个时候消费者要消费数据,那么每个消费者都需要获取最大可消 费的下标。

同时,Disruptor 不像传统的队列,分为一个队头指针和一个队尾指针,而 是只有一个角标(上图的 seq),它属于一个 volatile 变量,同时也是我们能够 不用锁操作就能实现 Disruptor 的原因之一,而且通过缓存行补充,避免伪共享 问题。该指针是通过一直自增的方式来获取下一个可写或者可读数据。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一名技术极客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值