关于Disruptor的分享

本文探讨了Disruptor框架的高效实现原理,包括环形缓冲区、无锁设计及缓存行填充等关键技术,并结合实际项目场景分析线上处理延迟问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一篇博客,万事开头难。有点粗糙。

介绍:

最近项目中需要修改bug,涉及到前面大牛写的用disruptor异步处理业务的场景。后来业务bug修复了,但是线上的处理特别慢,延迟将近一个小时,所以抽空记录下来学习的过程。不过由于本人才疏学浅,实在是能力有限,很多理解有问题的地方,希望用过的人能够帮我指正出来,一起学习。谢谢。 LMAX是一种新型零售金融交易平台,它能够以很低的延迟产生大量交易。这个系统是建立在JVM平台上,其核心是一个业务逻辑处理器,它能够在一个线程里每秒处理6百万订单。业务逻辑处理器完全是运行在内存中,使用事件源驱动方式。业务逻辑处理器的核心是Disruptor。 首先我们都知道并发编程的好处,看起来并行处理的效率比单线程的来的快的多,所以在许多涉及到高并发的场景中,但是在这里要打破并发处理更快的理解,这样方便理解disruptor为什么这样快。

第一点,数据结构。

disruptor采用的是ringbuffer,是一种环形数组,借一张盗来的图。 ![ringbuffer]

首先为什么要用数组,都知道大部分缓存都用链表队列。来对比一下链表和数组。

数组和链表的区别

数组是将元素在内存中连续存放,由于每个元素占用内存相同,可以通过下标迅速访问数组中任何元素。 但是如果要在数组中增加一个元素,需要移动大量元素,在内存中空出一个元素的空间,然后将要增加的元素放在其中。 同样的道理,如果想删除一个元素,同样需要移动大量元素去填掉被移动的元素。如果应用需要快速访问数据,很少或不插入和删除元素,就应该用数组。 链表恰好相反,链表中的元素在内存中不是顺序存储的,而是通过存在元素中的指针联系到一起。比如:上一个元素有个指针指到下一个元素, 以此类推,直到最后一个元素。如果要访问链表中一个元素,需要从第一个元素开始,一直找到需要的元素位置。但是增加和删除一个元素对于链表数据结构就非常简单了, 只要修改元素中的指针就可以了。如果应用需要经常插入和删除元素你就需要用链表数据结构了。 所以说场景中大部分消费者需要删除队列中的数据,所以需要链表的队列。而不是数组。 这里为什么可以用数组呢,因为场景中可以覆盖数据,而不需要删除数据,而且不需要扩容,因为是环形的。容量固定的,最好是2的幂数,这样方便后面生产消费获取位置。而且数组可以预加载相邻的元素。 而且它只维护了一个尾指针,用来帮助生产消费者获取位置。

第三点,无锁,缓存行填充 ,解决伪共享以及内存屏障的问题

一般来说锁是降低效率的。 对于共享数据。所以我认为如果我应用disruptor, 模式的话我会选单生产,多消费的模式,尽管它提供了多生产多消费的模式, 但是这样会有写入的竞争,会影响效率。读取数据的话,倒是无所谓。 这里还有涉及cpu,主内存的相关问题。尽管这才是disruptor快的真正原因,但是太过抽象,看懂一点,也不能很好理解。还是参考译文吧。 http://ifeve.com/disruptor-cacheline-padding/ ###Next 下一篇我会给出disruptor的demo代码并且结合项目中的业务场景,尝试找出线上处理没有达到期待的速度的原因。

参考文章:

http://ifeve.com/disruptor

转载于:https://my.oschina.net/u/2487314/blog/778784

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值