`
weigang.gao
  • 浏览: 491788 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

Disruptor入门教程(译)

 
阅读更多

Getting the Disruptor

获取Disruptor

 

 

The Disruptor jar file is available from Maven Central and can be integrated into your dependency manager of choice from there. You can also download the binary from our downloads page on the Wiki. The observant will note that these are just a link to the binaries on Maven Central.

Disruptor jar文件可以从Maven中央仓库获取,并且能集成到你的可选的依赖管理,你也能够从我们在WIKI上面的下载页面下载二进制文件。善于观察者将注意到这仅仅是一个连接到

Maven仓库的二进制文件

 

Basic Event Produce and Consume

生产者和消费者基本事件

 

To get started with the Disruptor we are going to consider very simple and contrived example, one that will pass a single long value from a producer to a consumer, where the consumer will simply print out the value. Firstly we will define the Event that will carry the data.

开始使用Disruptor之前 我们将思考专门设计的非常简单的例子,这个例子将在生产者与消费者之间传送Long值,在这里消费者仅仅打印出值。首先,我们定义能够搬运数据的事件

public class LongEvent
{
    private long value;

    public void set(long value)
    {
        this.value = value;
    }
}

 

 

 

In order to allow the Disruptor to preallocate these events for us, we need to an EventFactory that will perform the construction

为了允许Disruptor预先为我们分配这些事件,我们需要一个执行构造Event的事件工厂

import com.lmax.disruptor.EventFactory;

public class LongEventFactory implements EventFactory<LongEvent>
{
    public LongEvent newInstance()
    {
        return new LongEvent();
    }
}

 

 

 

Once we have the event defined we need to create a consumer that will handle these events. In our case all we want to do is print the value out the the console.

一旦我们有了确定的事件,我们需要创建一个能够处理这些事件消费者。在我们案例中我们想要做的就是在控制台打印出值。

import com.lmax.disruptor.EventHandler;

public class LongEventHandler implements EventHandler<LongEvent>
{
    public void onEvent(LongEvent event, long sequence, boolean endOfBatch)
    {
        System.out.println("Event: " + event);
    }
}

 

We will need a source for these events, for the sake of an example I am going to assume that the data is coming from some sort of I/O device, e.g. network or file in the form of a ByteBuffer.

我们需要这些事件的来源,例如我假定数据来源于某种I/O设备。比如,互联网或者以字节码形式存在文件。

import com.lmax.disruptor.RingBuffer;

public class LongEventProducer
{
    private final RingBuffer<LongEvent> ringBuffer;

    public LongEventProducer(RingBuffer<LongEvent> ringBuffer)
    {
        this.ringBuffer = ringBuffer;
    }

    public void onData(ByteBuffer bb)
    {
        long sequence = ringBuffer.next();  // Grab the next sequence
        try
        {
            LongEvent event = ringBuffer.get(sequence); // Get the entry in the Disruptor
                                                        // for the sequence
            event.set(bb.getLong(0));  // Fill with data
        }
        finally
        {
            ringBuffer.publish(sequence);
        }
    }
}

 

 

What becomes immediately obvious is that event publication becomes more invovled that using a simple queue. This is due to the desire for event preallocation. In requires (at the lowest level) a 2-phase approach to message publication, i.e. claim the slot in the ring buffer then publish the available data. It is also necessary to wrap publication in a try/finally block. If we claim a slot in the Ring Buffer (calling RingBuffer.next()) then we must publish this sequence. Failing to do can result in corruption of the state of the Disruptor. Specially, in the multi-producer case this will result in the consumers stalling and being unable to recover without a restart.

什么东西将立刻变得明显?事件发布变得相关东西(使用了一个简单队列)。这是由于事件需要预先分配。在需要(在最低的水平)2段式方法消息发布,也就是,

在ring buffer里面声明获取一个槽,然后发布可用的数据。使用try/finally块包裹发布是必须的。如果我们在Ring Buffer(调用RingBuffer.next())里声明获取了一个槽

,那么我们必须发布这个sequence。失败能够导致Disruptor情况糟糕。特别是在多生产者的情况下,这将导致消费者停顿并且不能够恢复,除非重启。

 

Using version 3 Translators

使用3.0版本的Translators

With version 3.0 of the Disruptor a richer Lambda-style API was added to help developers by encapsulating this complexity within the Ring Buffer, so post-3.0 the preferred approach for publishing messages is via the Event Publisher/Event Translator portion of the API. E.g.

使用3.0版本的Disruptor,通过把这种复查的东西封装到Ring Buffer里面, 一个更加丰富的Lambda风格的API被提供帮助开发人员。因此 发布信息的更佳的方式是通过帮助文档的Event Publisher/Event Translator部分。比如

import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.EventTranslatorOneArg;

public class LongEventProducerWithTranslator
{
    private final RingBuffer<LongEvent> ringBuffer;

    public LongEventProducerWithTranslator(RingBuffer<LongEvent> ringBuffer)
    {
        this.ringBuffer = ringBuffer;
    }

    private static final EventTranslatorOneArg<LongEvent, ByteBuffer> TRANSLATOR =
        new EventTranslatorOneArg<LongEvent, ByteBuffer>()
        {
            public void translateTo(LongEvent event, long sequence, ByteBuffer bb)
            {
                event.set(bb.getLong(0));
            }
        };

    public void onData(ByteBuffer bb)
    {
        ringBuffer.publishEvent(TRANSLATOR, bb);
    }
}

 

The other advantage of this approach is that the translator code can be pulled into a separate class and easily unit tested independently. The Disruptor provides a number of different interfaces (EventTranslator, EventTranslatorOneArg, EventTranslatorTwoArg, etc.) that can be implemented to provide translators. The reason for is to allow for the translators to be represented as static classes or non-capturing lambda (when Java 8 rolls around) as the arguments to the translation method are passed through the call on the Ring Buffer through to the translator.

使用这种方式这个优势是translator代码能够被提到一个单独的类中,容易独立地使用单元测试。Disruptor提供很多不同接口(EventTranslator, EventTranslatorOneArg, EventTranslatorTwoArg,等等),这些接口能过被实现成Translator.

 

The final step is to wire the whole thing together. It is possible to wire all of the components manually, however it can be a little bit complicated so a DSL is provided to simplify construction. Some of the more complicated options are not available via the DSL, however it is suitable for most circumstances.

最后一步是把整个事情连接在一起.可以手动连接所有组件,无论如何它有一点复查,因此DSL简化了构造。一些更加复杂的选项通过DSL是无法使用,无论如何,它适合于大部分情况。

import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.RingBuffer;
import java.nio.ByteBuffer;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class LongEventMain
{
    public static void main(String[] args) throws Exception
    {
        // Executor that will be used to construct new threads for consumers
        Executor executor = Executors.newCachedThreadPool();

        // The factory for the event
        LongEventFactory factory = new LongEventFactory();

        // Specify the size of the ring buffer, must be power of 2.
        int bufferSize = 1024;

        // Construct the Disruptor
        Disruptor<LongEvent> disruptor = new Disruptor<>(factory, bufferSize, executor);

        // Connect the handler
        disruptor.handleEventsWith(new LongEventHandler());

        // Start the Disruptor, starts all threads running
        disruptor.start();

        // Get the ring buffer from the Disruptor to be used for publishing.
        RingBuffer<LongEvent> ringBuffer = disruptor.getRingBuffer();

        LongEventProducer producer = new LongEventProducer(ringBuffer);

        ByteBuffer bb = ByteBuffer.allocate(8);
        for (long l = 0; true; l++)
        {
            bb.putLong(0, l);
            producer.onData(bb);
            Thread.sleep(1000);
        }
    }
}

 

 

Basic Tuning Options

基本的t调优选项

 

Using the above approach will work functionally in the widest set of deployment scenarios. However, if you able to make certain assumptions about the hardware and software environment that the Disruptor will run in then you can take advantage of a number of tuning options to improve performance. There are 2 main options for tuning, single vs. multiple producers and alternative wait strategies.

使用上面的方法将功能工作在最宽的部署场景。无论如何,如果你能确定Disruptor运行在硬件和软件的环境,那么你可以利用大量的调优选项来提高性能。有2个主要的

调优选项,单个生产者与多个生产者对比和可供选择的等待策略。

 

Single vs. Multiple Producers

单个生产者与多个生产者对比

One of the best ways to improve performance in concurrect systems is to ahere to the Single Writer Princple, this applies to the Disruptor. If you are in the situation where there will only ever be a single thread producing events into the Disruptor, then you can take advantage of this to gain additional performance.

在并发系统中改进性能最好的方法之一是Single Writer原则,这适用于Disruptor.如果你正好需要单个线程来生产事件,那么你可利用这个获取附加性能。

public class LongEventMain
{
    public static void main(String[] args) throws Exception
    {
        //.....
        // Construct the Disruptor with a SingleProducerSequencer
        Disruptor<LongEvent> disruptor = new Disruptor(factory, 
                                                       bufferSize,
                                                       ProducerType.SINGLE, // Single producer
                                                       new BlockingWaitStrategy(),
                                                       executor);

        //.....
    }
}

 

 

参考:https://github.com/LMAX-Exchange/disruptor/wiki/Getting-Started

分享到:
评论

相关推荐

    Disruptor学习(1)

    《Disruptor学习(1)——深入理解高性能并发框架》 Disruptor是英国LMAX公司开发的一个开源并发框架,其设计目标是为了提供极低延迟的并发处理能力。在金融交易系统等领域,对于高频率、低延迟的需求尤为重要,...

    disruptor-3.3.0-API文档-中英对照版.zip

    赠送jar包:disruptor-3.3.0.jar; 赠送原API文档:disruptor-3.3.0-javadoc.jar; 赠送源代码:disruptor-3.3.0-sources.jar; 赠送Maven依赖信息文件:disruptor-3.3.0.pom; 包含翻译后的API文档:disruptor-...

    Disruptor并发框架中文参考文档

    ### Disruptor并发框架知识点详解 #### 一、Disruptor简介及原理 **Disruptor** 是一款高性能、低延迟的并发框架,它通过无锁设计实现了高效的队列操作,从而大大提升了多线程环境下的性能表现。该框架于2011年...

    无锁队列Disruptor超详细教程

    无锁队列Disruptor是LMAX公司为解决内存队列延迟问题而设计的一种高性能队列,它在Java领域被誉为最高性能的队列。与Kafka等服务间消息队列不同,Disruptor主要用于线程间的消息传递。由于其卓越的性能,基于...

    springboot整合Disruptor并发编程框架 #资源达人分享计划#

    SpringBoot整合Disruptor并发编程框架是针对高并发场景下性能优化的一种技术实践。Disruptor是由LMAX公司开发的一款高性能、低延迟的并发工具,它通过消除线程间的锁竞争,大大提升了多线程环境下的处理速度。...

    spring-boot-starter-disruptor.zip

    《Spring Boot Starter Disruptor深度解析》 在现代软件开发中,高性能和低延迟往往是系统设计的关键要素。Spring Boot作为Java领域最受欢迎的微服务框架,提供了丰富的启动器(starters)来简化开发工作。"spring-...

    disruptor-3.4.4.jar disruptor 3.4.4 jar 官方github下载

    disruptor-3.4.4.jar 官方github下载 亲测可用,大家赶紧下载吧 后续再补充其他常用jar(但不好下载的)

    Disruptor3.x Disruptor使用方式

    Disruptor3.x Disruptor使用方式 EventHandler[] eventHandlers=new DisruptorEventHandler[]{new DisruptorEventHandler()}; DisruptorPublisher dp=new DisruptorPublisher(1024, eventHandlers); dp.start(); ...

    DisruptorDemo.zip

    《Disruptor技术详解——基于DisruptorDemo.zip实例解析》 Disruptor,由LMAX公司开发并开源,是一款高性能、低延迟的并发工具,主要用于优化多线程间的通信。它采用一种环形缓冲区(Ring Buffer)的设计,极大地...

    Disruptor demo

    Disruptor是一款高性能的并发工具库,由LMAX公司开发并开源,主要应用于高频率交易系统。它通过优化线程间通信的方式,极大地提升了多线程环境下的数据处理速度。Disruptor的设计理念是避免传统的锁机制,转而采用一...

    disruptor jar包+Demo+Api

    《Disruptor 框架详解与应用实例》 Disruptor 是一款高性能的并发工具库,由英国的 LMAX 公司开发并开源。它主要用于优化多线程环境下的数据共享,尤其在金融交易系统中表现卓越。Disruptor 的核心设计是一个环形...

    disruptor 多个消费者

    Disruptor是由LMAX公司开发的一种高性能的并发编程框架,主要应用于金融交易系统。它通过优化数据共享方式,显著提高了多线程环境下的处理速度。在"Disruptor 多个消费者"的场景中,我们可以深入理解Disruptor如何...

    disruptor-3.3.8.jar

    Error: java.lang.NoSuchMethodError: com.lmax.disruptor.dsl.Disruptor.&lt;init&gt;(Lcom/lmax/disruptor/EventFactory;ILjava/util/concurrent/ThreadFactory;Lcom/lmax/disruptor/dsl/ProducerType;Lcom/lmax/...

    Disruptor C++版(仅支持单生产者)

    Disruptor是由LMAX公司开发的一种高性能的并发编程框架,主要应用于金融交易系统。它以其高效、低延迟的事件处理机制而闻名。在C++版本的Disruptor中,我们同样可以享受到这种高效的并发能力,尤其适用于需要大量...

    disruptor-3.3.0-API文档-中文版.zip

    赠送jar包:disruptor-3.3.0.jar; 赠送原API文档:disruptor-3.3.0-javadoc.jar; 赠送源代码:disruptor-3.3.0-sources.jar; 赠送Maven依赖信息文件:disruptor-3.3.0.pom; 包含翻译后的API文档:disruptor-...

    disruptor案例加简单说明

    简单讲解disruptor并附上demo

    Disruptor应用实例

    《Disruptor应用实例》 Disruptor是高性能并发编程领域的一个重要工具,由LMAX公司开发并开源,主要用于优化多线程环境下的数据处理。它通过一种创新的数据同步方式,极大地提升了系统的吞吐量和响应速度。在本文中...

    disruptor-3.4.2.jar 及 disruptor-3.4.2-sources.jar

    disruptor-3.4.2.jar 工具jar包 及 disruptor-3.4.2-sources.jar, Disruptor它是一个开源的并发框架,并获得2011 Duke’s 程序框架创新奖,能够在无锁的情况下实现网络的Queue并发操作,是 log4j2 引用的 jar 包

    LMAX disruptor jar包+Demo+Api+src源码 disruptor-3.0.1.jar

    LMAX Disruptor是一款高性能的消息处理框架,由LMAX公司开发并开源,它在金融交易领域有着广泛的应用。Disruptor的设计目标是解决多线程环境下的数据共享问题,通过优化并发性能,实现极低的延迟和高吞吐量。在Java...

Global site tag (gtag.js) - Google Analytics