Disruptor sharing data between threads without competition

Source: Internet
Author: User
Tags intel core i7

The role of the queue is to buffer

Buffer into the space of the queue.

No competition for shared data between threads

Original address author Trisha Translator: Li Tongjie

LMAX Disruptor is an open-source concurrency framework, and is awarded the Duke ' s Program Framework Innovation Award. This article will use a chart to introduce you to what disruptor is, what to do, and a brief introduction to the principles behind the implementation.

What is Disruptor?

Disruptor is a intra-thread communication framework that is used to share data in threads. LMAX creates disruptor as part of a robust messaging architecture and designs it as a very fast way to share data in different components.
Based on mechanical sympathy (understanding of the underlying hardware of the computer), basic computer science and domain-driven design, Disruptor has evolved into a framework to help developers solve many tedious concurrent programming problems.
Many architectures commonly use a queue to share data between threads (that is, to send messages). Figure 1 shows an example of sending messages in different stages by using queues (each blue circle represents a thread).

Figure 1

This architecture allows producer threads (Stage1 in Figure 1) to continue with the next step when Stage2 is too busy to handle immediately, providing a way to resolve data congestion in the system. Here the queue can be seen as a buffer between different threads.

In this simplest case, disruptor can be used instead of queues as a tool for passing messages on different threads (2).

Figure 2

This data structure is called Ringbuffer, which is implemented by arrays. The Stage1 thread puts the data into Ringbuffer, while the STAGE2 thread reads the data from the Ringbuffer.

In Figure 2, you can see that there are ordinal numbers in each cell in the Ringbuffer, and ringbuffer the maximum (up-to-date) number of real-time monitoring values, which points to the last grid in Ringbuffer. The serial numbers will grow with more and more data being added into the ringbuffer.

The key to Disruptor is that it is designed to be non-competitive within the framework. This is achieved by adhering to the Single-writer principle that only one piece of data can be written to a data block. Following such rules makes disruptor avoid costly CAS locks, which also makes disruptor very fast.

Disruptor reduces competition by using Ringbuffer and each event handler (Eventprocessor) to monitor their respective serial numbers. This allows the event handler to update only the ordinal number that it obtains. This concept is further elaborated when introduced to read and write data to Ringbuffer.

Publish to Disruptor

Writing data to Ringbuffer requires a two-phase commit (two-phase commit). First, the Stage1 thread, the publisher, must determine which of the next ringbuffer can be inserted, as shown in 3.

Figure 3

Ringbuffer holds the ordinal of the most recently written lattice (18 in Figure 3) to determine the ordinal of the next insert.

Ringbuffer determines whether the next insert is idle by checking the current sequence number that all event handlers are reading from the Ringbuffer.

Figure 4 shows the next insert found.

Figure 4

When the publisher gets the next ordinal, it can get the object in that lattice and can manipulate the object. You can think of a lattice as a simple container that can be written to any value.

At the same time, when the publisher processes 19 of data, the serial number of the Ringbuffer is still 18, so the other event handlers will not read the data in the 19 grid.

Figure 5 shows that the object changes are saved in the Ringbuffer.

Figure 5

Eventually, when the publisher eventually writes data to 19, it notifies Ringbuffer to publish 19 of the data. At this point, ringbuffer updates the serial number and all the event handlers that read the data from Ringbuffer can see the data in the 19 grid.

data read in Ringbuffer

The Disruptor framework contains a batcheventprocessor that can read data from Ringbuffer, which outlines how it works and highlights its design.

When the publisher asks Ringbuffer for the next space to write, an event handler that actually does not really consume events from the Ringbuffer will monitor the latest sequence number it processes and request the next sequence number it needs.

Figure 5 shows the event handler waiting for the next sequence number.

Figure 6

Instead of asking for an ordinal number directly to the Ringbuffer, the event handler requests the sequence number through Sequencebarrier to Ringbuffer. The specifics of the implementation are not important to our understanding, but the following can be seen as a clear purpose.

As shown in Stage2 6, the maximum sequence number of an event handler is 16. It calls WAITFOR (17) to Sequencebarrier to get the data in 17. Wait for the next ordinal because there is no data written to the Ringbuffer,stage2 event handler pending. If so, there is nothing to deal with. However, as shown in 6, Ringbuffer has been populated to 18, so the WAITFOR function will return 18 and notify the event handler, which can read data including up to 18 cells, as shown in 7.

Figure 7

This method provides a very good batch processing function, which can be seen in the Batcheventprocessor source code. The source code directly to the Ringbuffer in bulk to obtain from the next sequence number to the maximum can be obtained in the ordinal data.

You can use the batch processing feature by implementing EventHandler. There are examples of how batch processing is used in disruptor performance tests, such as Fizzbuzzeventhandler.

is the low latency queue?

Of course, disruptor can be used as a low-latency queue. Our test data for previous versions of Disruptor shows that running on an Intel Core I7-2720QM processor 2.2 GHz uses Java 1.6.0_25 In the 64-bit Ubuntu 11.04 three-tier pipeline mode architecture, Disruptor is much faster than arrayblockingqueue. Table 1 shows the per-hop delay in the pipeline. For more detailed information about this test, see the disruptor technical file.

But don't get disruptor based on deferred data-it's just a solution to a particular performance problem because it's not.

something cooler.

An interesting thing is how disruptor supports dependencies between system components and does not compete when sharing data between threads.

Disruptor is designed to adhere to the single-writer principle to achieve zero competition, where each data bit can only be written by one thread. However, this does not mean that you cannot use multiple threads to read data, which is what disruptor supports.

The Disruptor system was originally designed to support periodic, similar pipelining events that need to occur in a particular order, and this requirement is not uncommon in enterprise application development. Figure 8 shows the standard Level 3 pipeline.

Figure 8

First, each event is written to the hard disk (log) for later recovery. Second, these events are replicated to the backup server. Only after these two phases, the system begins to process the business logic.

It is a logical approach to perform the last operation sequentially, but it is not the most efficient method. Log and copy operations can be performed synchronously because they are independent of each other. But the business logic must be executed before they are all done. Figure 9 shows that they can be interdependent in parallel.

Figure 9

If you use Disruptor, the first two stages (log and copy) can read data directly from the Ringbuffer. As shown in the 7 simplification diagram, they all use a single sequence barrier to get the next available sequence number from Ringbuffer. They record the serial numbers they used so they know that those events have been read and can use Batcheventprocessor to get events in bulk.

Business logic can also read events from the same ringbuffer, but only for events that have already been processed in the first two phases. This is achieved by joining the second Sequencebarrier, which monitors the event handlers that handle the log and the event handlers that are being copied, and returns the smaller ordinal number of two processors when the maximum readable sequence number is requested.

When each event handler uses Sequencebarrier to determine which events are safe to read from the Ringbuffer, the events are read from.

Figure 10

There are many event handlers that can read sequence numbers from Ringbuffer, including log event handlers, replication event handlers, and so on, but only one processor can increment the serial number. This ensures that there is no competition for shared data.

What if there are multiple publishers?

Disruptor also supports writing to Ringbuffer by multiple publishers. Of course, because of this, two different event handlers will inevitably be written to the same lattice, which will create a competition. Disruptor provides a way for claimstrategy to deal with multiple publishers.

Conclusion

Here, I've covered in general how the Disruptor framework shares data in a high-performance thread and simply explains its rationale. For more advanced event handlers and for Ringbuffer to request space and wait for the next sequence number, and many other strategies are not involved here, Disruptor is open source, go to the code to search it.

Note 1: Java Magazine from Oracle Publishing, http://www.oracle.com/technetwork/cn/java/javamagazine/index.html

original articles, reproduced please specify: reproduced from the Concurrent programming network –ifeve.com This article link address: sharing data between threads without competition

Disruptor sharing data between threads without competition

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.