Disruptor学习笔记(一):基本原理和概念
一、Disruptor基本原理
在多线程开发中,我们常常遇到这样一种场景:一些线程接受用户请求,另外一些线程处理这些请求。比如日志处理中的日志输入和告警。这种典型的生产者消费者场景十分常见,而生产者消费者模式的核心就是阻塞队列。由于阻塞队列会涉及大量的锁竞争和线程阻塞,都是非常耗费CPU的操作,因此阻塞队列的性能好坏能够在很大程度上决定上层应用的性能瓶颈。
JAVA中用BlockingQueue这个接口来描述阻塞队列,有数组实现的有界阻塞队列为 ArrayBlockingQueue,用链表实现的无界阻塞队列为LinkedBlockingQueue,除此之外还有优先级阻塞队列 PriorityBlockingQueue,这些阻塞队列除了自身特有逻辑外,都采用基于悲观锁的并发控制。这样的并发机制会有严重的锁冲突,大大影响并发性能。Disruptor满足了我们的要求。
锁是用来做并发最简单的方式,当然其代价也是最高的。内核态的锁的时候需要操作系统进行一次上下文切换,等待锁的线程会被挂起直至锁释放。
使用了Ringbuffer,内存屏障,乐观并发控制等众多优化手段后,Disrupter的阻塞队列与传统的阻塞队列相比有超过10倍的吞吐率。
Disruptor的主要设计思想是无锁的高并发,在设计上采用内存屏障的机制和CAS操作实现此思想。主流的并发程序 都离不开锁对资源的管控,或者尽量避开锁的使用。
其主要的实现原理总结有如下三点:
采用消费者-生产者模型进行读写的分离。
用循环缓存(实际是一个循环队列)实现了数据的暂存和读写速度的匹配。
用内存屏障加序列号的方式实现了无锁的并发机制。
为什么Disruptor的速度这么快?
我们知道Disruptor速度很快,但是为什么呢?
Disruptor没有使用很影响性能锁 。取而代之的是,在需要确保操作是线程安全的(特别是,在多生产者的环境下,更新下一个可用的序列号)地方,我们使用CAS(Compare And Swap/Set)操作。这是一个CPU级别的指令,它的工作方式有点像乐观锁——CPU去更新一个值,但如果想改的值不是原来的值,操作就失败,反之则去更新这个值。
说句题外话,Java中AtomicInteger也使用了CAS操作来保证原子性。在并发控制中,CAS操作是十分重要的。
CAS操作是CPU级别的指令,在Java中CAS操作在Unsafe类中(Unsafe,见名知意,这个类是不安全的,不建议在实际开发的时候使用)。关于CAS操作的原理网上有很多,在此不过多说明了。
另一个重要的因素是Disruptor消除了伪共享。 下面引用网上的一段话,来解释下什么是伪共享。
缓存系统中是以缓存行(cache line)为单位存储的。缓存行是 2 的整数幂个连续字节,一般为 32-256 个字节。最常见的缓存行大小是 64个字节。
当多线程修改互相独立的变量时,如果这些变量共享同一个缓存行,就会无意中影响彼此的性能,这就是伪共享。缓存行上的写竞争是运行在 SMP 系统中并行线程实现可伸缩性最重要的限制因素。有人将伪共享描述成无声的性能杀手,因为从代码中很难看清楚是否会出现伪共享。
第三个原因是Disruptor采用了RingBuffer。Ring Buffer 是一个数组,它比链表要快,而且有一个容易预测的访问模式,数据可以在硬件层面预加载到高速缓存,极大的提高了数据访问的速度。
RingBuffer可以预先分配内存,并且保持数组元素永远有效。这意味着内存垃圾收集(GC)在这种情况下几乎什么也不用做。
二、Disuptor基本概念
RingBuffer:Ringbuffer是一个环形缓冲区,是Disruptor的核心。
Sequencer:序号管理器,使消费者和生产者之前快速正确地传输数据。
Sequence:RingBuffer中每个数据的序号,用于跟踪ringbuffer中任务的变化和消费者的消费情况。
SequenceBarrier:序号栅栏,管理和协调生产者的游标序号和各个消费者的序号,确保生产者不会覆盖消费者未来得及处理的消息,确保存在依赖的消费者之间能够按照正确的顺序处理。
Event:生产者和消费者之间进行交换的数据称为事件。
EventProcessor:事件处理器,监听RingBuffer的事件,并消费可用事件,从RingBuffer读取的事件会交由实际的生产者实现类来消费;它会一直侦听下一个可用的序号,直到该序号对应的事件已经准备好。
EventHandler:业务处理器,是实际消费者的接口,完成具体的业务逻辑实现,第三方实现该接口;代表着消费者。
Producer:生产者接口,第三方线程充当该角色,producer向RingBuffer写入事件。
本文引用了很多网上的博客内容,由衷地感谢他们乐于分享的精神。
Disruptor学习笔记(一):基本原理和概念的更多相关文章
- .NET Remoting学习笔记(一)概念
目录 .NET Remoting学习笔记(一)概念 .NET Remoting学习笔记(二)激活方式 .NET Remoting学习笔记(三)信道 背景 自接触编程以来,一直听过这个名词Remotin ...
- 【转载】.NET Remoting学习笔记(一)概念
目录 .NET Remoting学习笔记(一)概念 .NET Remoting学习笔记(二)激活方式 .NET Remoting学习笔记(三)信道 背景 自接触编程以来,一直听过这个名词Remotin ...
- Disruptor学习笔记
前言 以前一直听说有Disruptor这个东西,都说性能很强大,所以这几天自己也看了一下. 下面是自己的学习笔记,另外推荐几篇自己看到写的比较好的博客: Disruptor——一种可替代有界队列完成并 ...
- 【原】Learning Spark (Python版) 学习笔记(一)----RDD 基本概念与命令
<Learning Spark>这本书算是Spark入门的必读书了,中文版是<Spark快速大数据分析>,不过豆瓣书评很有意思的是,英文原版评分7.4,评论都说入门而已深入不足 ...
- Spring学习笔记一:基础概念
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6774310.html 一:Spring是什么 Spring的主要作用是作为对象的容器. 传统编程中,我们 ...
- Learning Spark (Python版) 学习笔记(一)----RDD 基本概念与命令
<Learning Spark>这本书算是Spark入门的必读书了,中文版是<Spark快速大数据分析>,不过豆瓣书评很有意思的是,英文原版评分7.4,评论都说入门而已深入不足 ...
- [No000094]SVN学习笔记4-版本库概念与部分日常操作
基本概念 版本库 Subversion 使用集中的数据库,它包含了所有的版本控制文件及其完整历史.这个数据库就是版本库.版本库通常位于运行 Subversion 服务器的文件服务器上,向 Subver ...
- UNET学习笔记3 - 网络系统的概念
服务器和 HOST 在Unity游戏里,一个游戏一般有一个服务器和多个客户端组成,但也可以没有服务器,用某一个客户端来同时做服务器用,这种就叫Host 在Host上的客户端叫Local Client, ...
- C++学习笔记39:进程概念
进程的基本概念 进程是描述程序执行过程和资源共享的基本单位 主要目的:控制和协调程序的执行 进程相关函数 用户与组ID函数 创建进程:system(),fork(),exec() 终止进程:kill( ...
随机推荐
- Django - 缓存应用
Django缓存应用: https://www.cnblogs.com/zuoshoushizi/p/7850281.html https://www.cnblogs.com/alice-bj/p/9 ...
- 2018/03/29 每日一个Linux命令 之 ping
ping 用于测试两及其网络是否通 主要用于检测网络是否通畅. -- 具体语法 ping [-dfnqrRv][-c<完成次数>][-i<间隔秒数>][-I<网络界面&g ...
- 学习计划 mysql explain执行计划任务详解
我们在之前已经找到了需要优化的SQL,但是怎么知道它的那些方面需要优化呢? explain就是为了这个使用的. explain显示了 mysql 如何使用索引来处理select语句以及连接表.可以帮助 ...
- Callable接口解析
1.接口的定义: public interface Callable<V> { V call() throws Exception; } 2.Callable和Runnable的异同 先看 ...
- Python开发【笔记】:关闭线程的方法
1.通过API进行线程关闭 import threading import time import inspect import ctypes def _async_raise(tid, exctyp ...
- Java bytesToHexString 解析
一.代码 /** * Convert byte[] to hex string * * @param src byte[] data * @return hex string */ public st ...
- EL--Expression Language
EL 存取变量数据的方法很简单,例如:${username}.它的意思是取出某一范围中名称为username的变量.因为我们并没有指定哪一个 范围的username,所以它的默认值会先从Page 范围 ...
- UVA 11136 Hoax or what (multiset)
题目大意: 超时进行促销.把账单放入一个箱子里 每次拿取数额最大的和最小的,给出 最大-最小 的钱. 问n天总共要给出多少钱. 思路分析: multiset 上直接进行模拟 注意要使用long lo ...
- 百度编辑器UEditor源码模式下过滤div/style等html标签
UEditor在html代码模式下,当输入带有<div style="">.<iframe>这类带有html标签的内容时,切换为编辑器模式后,会发现输入的内 ...
- JS在不同js文件中互相调用
例如有这样一个html,里面有一个按钮,当按下时调用b.js文件中的方法b().而b()中又要调用a.js文件中的方法a().若要实现这个功能,必须注意,将要引入的Js文件代码放在</body& ...