关于Disruptor的分享

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

介绍:

最近项目中须要修改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异步

相关文章
相关标签/搜索