Disruptor

Disruptor高性能之道—无锁实现(CAS)

旧时模样 提交于 2020-01-14 04:43:49
目录 一、前言 二、RingBuffer简介 三、依赖链 四、无锁竞争实现 1、生产者和消费者竞争实现 2、生产者和生产者竞争实现 3、消费者和消费者竞争实现 4、消费组内的消费者竞争实现 5、实现总结 五、惯例 一、前言 说到Disruptor都会提到其牛逼的性能,一说其性能大家都应该会想到它的无锁实现。大家都会说因为它是无锁实现的(重要因素,并不是唯一因素),所以它的性能很好。 那么它是怎样通过无锁的方式解决了多线程(消费者和生产者)之间的竞争呢?本文将给大家做一个基本的分析。 二、RingBuffer简介 熟悉或者了解Disruptor同学都知道,Disruptor采用了RingBuffer的数据结构来存储数据,而不是像BlockingQueue那样使用的队列。RingBuffer就是一个基于数据组实现的环形结构(如果还有不了解的同学,可以先行百度了解下)。生产者每生产一个数据就向前移动一格,而消费者每消费一个数据也向前移动一格。 图片来自网络 另外RingBuffer的大小是创建的时候就固定的,且其会预先分配好所有内存。即每个位置都会提前填充好对应的数据对象(一般是一个空对象)。然后每次生产者生成数据的时候仅仅是拿到这个位置的数据对象,然后将数据填充到(如通过setter)该对象中(该步骤由业务代码自己完成)。这样就避免了因频繁的创建和销毁对象而导致的不必要的对象回收

guava的eventBus和disruptor比较

你。 提交于 2020-01-10 05:49:00
EventBus: 基于观察者模式实现的, 本文基于同步模式来操作 ;这里只介绍下几个常用操作的代码实现: register:注册观察者实现:主要就是以把观察者观察的类key,同类观察者的set集合为value构成一个ConcurrenHashMap 代码如下: private final ConcurrentMap<Class<?>, CopyOnWriteArraySet<Subscriber>> subscribers = Maps.newConcurrentMap(); 这里有两步加锁:map分段锁,copyOnWriteArraySet读写锁; EventBus.post(Object):发送事件实现:根据事件的class找subscribers中的观察者,通过反射执行所有观察者的@Subscribe注解注释的方法; 代码如下: public void post(Object event) { Iterator<Subscriber> eventSubscribers = subscribers.getSubscribers(event); if (eventSubscribers.hasNext()) { dispatcher.dispatch(event, eventSubscribers); } else if (!(event instanceof

Disruptor的简单介绍与应用

◇◆丶佛笑我妖孽 提交于 2020-01-07 22:47:31
前言 最近工作比较忙,在工作项目中,看了很多人都自己实现了一套数据任务处理机制,个人感觉有点乱,且也方便他人的后续维护,所以想到了一种数据处理模式,即生产者、缓冲队列、消费者的模式来统一大家的实现逻辑。 下面时是对Disruptor基本使用的演示。使用中需要引入依赖 <dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.4.2</version> </dependency> 名称解释 Ring Buffer 环境的缓存区,3.0版本以前被认为是Disruptor的主要成员。3.0版本以后,环形缓冲区只负责通过Disruptor的事件方式来对数据进行存储和更新。在一些高级的应用场景中,Ring Buffer可以由用户的自定义实现完全替代。 Sequence Disruptor使用Sequence作为一种方法来确定特定组件的位置。每个使用者(EventProcessor)与Disruptor本身一样维护一个序列。大多数并发代码依赖于这些序列值的移动,因此序列支持AtomicLong的许多当前特性。事实上,两者之间唯一真正的区别是序列包含额外的功能,以防止序列和其他值之间的错误共享。 Sequencer Sequencer是真正的核心,该接口的两个实现(单生产者,

Disruptor的简单介绍与应用

扶醉桌前 提交于 2020-01-07 22:40:36
前言 最近工作比较忙,在工作项目中,看了很多人都自己实现了一套数据任务处理机制,个人感觉有点乱,且也方便他人的后续维护,所以想到了一种数据处理模式,即生产者、缓冲队列、消费者的模式来统一大家的实现逻辑。 下面时是对Disruptor基本使用的演示。使用中需要引入依赖 <dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.4.2</version> </dependency> 名称解释 Ring Buffer 环境的缓存区,3.0版本以前被认为是Disruptor的主要成员。3.0版本以后,环形缓冲区只负责通过Disruptor的事件方式来对数据进行存储和更新。在一些高级的应用场景中,Ring Buffer可以由用户的自定义实现完全替代。 Sequence Disruptor使用Sequence作为一种方法来确定特定组件的位置。每个使用者(EventProcessor)与Disruptor本身一样维护一个序列。大多数并发代码依赖于这些序列值的移动,因此序列支持AtomicLong的许多当前特性。事实上,两者之间唯一真正的区别是序列包含额外的功能,以防止序列和其他值之间的错误共享。 Sequencer Sequencer是真正的核心,该接口的两个实现(单生产者,

Disruptor的简单介绍与应用

自古美人都是妖i 提交于 2020-01-07 21:51:43
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 前言 最近工作比较忙,在工作项目中,看了很多人都自己实现了一套数据任务处理机制,个人感觉有点乱,且也方便他人的后续维护,所以想到了一种数据处理模式,即生产者、缓冲队列、消费者的模式来统一大家的实现逻辑。 下面时是对Disruptor基本使用的演示。使用中需要引入依赖 <dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.4.2</version> </dependency> 名称解释 Ring Buffer 环境的缓存区,3.0版本以前被认为是Disruptor的主要成员。3.0版本以后,环形缓冲区只负责通过Disruptor的事件方式来对数据进行存储和更新。在一些高级的应用场景中,Ring Buffer可以由用户的自定义实现完全替代。 Sequence Disruptor使用Sequence作为一种方法来确定特定组件的位置。每个使用者(EventProcessor)与Disruptor本身一样维护一个序列。大多数并发代码依赖于这些序列值的移动,因此序列支持AtomicLong的许多当前特性。事实上,两者之间唯一真正的区别是序列包含额外的功能,以防止序列和其他值之间的错误共享。

Disruptor并发框架

寵の児 提交于 2019-12-16 00:28:47
Disruptor并发框架 什么是Disruptor Disruptor的设计方案 Disruptor实现特征 Disruptor实现生产与消费 Pom Maven依赖信息 首先声明一个Event来包含需要传递的数据 声明 EventFactory 事件消费者 生产者 执行调用 什么是ringbuffer 优点 RingBuffer底层实现 Disruptor的核心概念 RingBuffer SequenceDisruptor Sequencer Sequence Barrier Wait Strategy Event EventProcessor EventHandler Producer 什么是Disruptor Martin Fowler在自己网站上写了一篇LMAX架构的文章,在文章中他介绍了LMAX是一种新型零售金融交易平台,它能够以很低的延迟产生大量交易。这个系统是建立在JVM平台上,其核心是一个业务逻辑处理器,它能够在一个线程里每秒处理6百万订单。业务逻辑处理器完全是运行在内存中,使`用事件源驱动方式。业务逻辑处理器的核心是 Disruptor 。 Disruptor它是一个开源的并发框架,并获得2011 Duke’s 程序框架创新奖,能够在无锁的情况下实现网络的Queue并发操作。 Disruptor是一个高性能的异步处理框架,或者可以认为是最快的消息框架

Windows下安装Hive与问题

与世无争的帅哥 提交于 2019-12-06 02:45:27
下载与安装 hive必须依赖hadoop,所以先安装hadoop,可以参考 hadoop安装 注意hive一般2.x.x就对应hadoop的2.y.y版本,3.x.x就需要hadoop的3.y.y版本。 hive下载 hive download Hive下载 hive wiki 高版本的hive中没有在windows下的运行的脚本,可以在 hive windows运行脚本 下载,覆盖对应的bin目录就可以了。 解压: HIVE_HOME目录 hive配置文件目录 Hive依赖Hadoop,记得配置HADOOP_HOME,因为启动基本中会使用到,也可以直接配置到hive-env.sh文件中,但是windows下不会使用这个配置文件,具体的可以看一下运行时候脚本。 特别注意,如果遇到类似下面的错误: java.lang.NoSuchMethodError: com.lmax.disruptor.dsl.Disruptor.<init>(Lcom/lmax/disruptor/EventFactory;ILjava/util/concurrent/ThreadFactory;Lcom/lmax/disruptor/dsl/ProducerType;Lcom/lmax/disruptor/WaitStrategy;)V 把%HADOOP_HOME%\share\hadoop\yarn

Disruptor (5) - 使用的不同场景

a 夏天 提交于 2019-12-05 22:35:47
handleEventsWith & handleEventsWithWorkerPool 在disruptor框架调用start方法之前,往往需要将消息的消费者指定给disruptor框架。 disruptor. handleEventsWith (EventHandler... handlers),将多个 EventHandler 的实现类传入方法,封装成一个 EventHandlerGroup 。 disruptor. handleEventsWithWorkerPool (WorkHandler... handlers),将多个 WorkHandler 的实现类传入方法,封装成一个 EventHandlerGroup 。 不同点 handleEventsWith方法的 EventHandlerGroup 中的每个消费者都会对同一条消息m进行消费,各个消费者之间不存在竞争。 handleEventsWithWorkerPool方法返回的 EventHandlerGroup ,Group的消费者对于同一条消息m不重复消费;如果c0消费了消息m,则c1不再消费消息m。 所以: 对于独立消费的消费者,应当实现EventHandler接口。对于不重复消费的消费者,应当实现WorkHandler接口。 从代码层面而言, 有不同的具体实现来支持不同的模式 ConsumerInfo

Disruptor (4) - shutdown

两盒软妹~` 提交于 2019-12-05 19:15:40
Disruptor.shutdown 方法阻塞至所有事件得到处理。 循环调用hasBacklog()判定当前 ringBuffer.getCursor()<生产分配的游标> > consumer的lastSequence<消费者序号> ,表示还未处理完结。 public void shutdown(final long timeout, final TimeUnit timeUnit) throws TimeoutException { final long timeOutAt = System.currentTimeMillis() + timeUnit.toMillis(timeout); while (hasBacklog()) { if (timeout >= 0 && System.currentTimeMillis() > timeOutAt) { throw TimeoutException.INSTANCE; } // Busy spin try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } halt(); } private boolean hasBacklog() { final

Disruptor: Gating Sequence

匿名 (未验证) 提交于 2019-12-03 09:02:45
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试): 问题: I am studying Disruptor in Java. I do not understand what's meaning of gating sequence. I know it core part is ring buffer and every buffer is associated with a sequence number. 回答1: The purpose of gating sequences is to gate publishers to prevent the RingBuffer from wrapping. 回答2: Actually the core part of LMAX's implementation is the Sequencer and its Sequence s. And so the ringBuffer implement those. The gatingSequences that you are referring to act as a cursor to each Sequencer that is "Subscribed" to the targeted ringBuffer (or other