Dissecting the Disruptor: How do I read from the ring buffer?

The next in the series of understanding the Disruptor pattern developed at LMAX.

After the last post we
all understand ring buffers and how awesome they are.  Unfortunately
for you, I have not said anything about how to actually populate them or
read from them when you’re using the Disruptor.

ConsumerBarriers and Consumers
I’m going to approach this slightly backwards, because it’s probably
easier to understand in the long run.  Assuming that some magic has
populated it: how do you read something from the ring buffer?

(OK, I’m starting to regret using Paint/Gimp.
 Although it’s an excellent excuse to purchase a graphics tablet if I
do continue down this road.  Also UML gurus are probably cursing my name
right now.)

Your Consumer is the thread that wants to get something off the buffer.  It has access to aConsumerBarrier, which is created by the RingBuffer and interacts with it on behalf of theConsumer.
 While the ring buffer obviously needs a sequence number to figure out
what the next available slot is, the consumer also needs to know which
sequence number it’s up to – each consumer needs to be able to figure
out which sequence number it’s expecting to see next.  So in the case
above, the consumer has dealt with everything in the ring buffer up to
and including 8, so it’s expecting to see 9 next.

The consumer calls waitFor on the ConsumerBarrier with the sequence number it wants next

    final long availableSeq = consumerBarrier.waitFor(nextSequence);

and the ConsumerBarrier returns the highest sequence number available in the ring buffer – in the example above, 12.  The ConsumerBarrier has a WaitStrategy which
it uses to decide how to wait for this sequence number – I won’t go
into details of that right now, the code has comments in outlining the
advantages and disadvantages of each.

Now what?
So the consumer has been hanging around waiting for more stuff to get
written to the ring buffer, and it’s been told what has been written –
entries 9, 10, 11 and 12.  Now they’re there, the consumer can ask the ConsumerBarrier to fetch them.

As it’s fetching them, the Consumer is updating its own cursor.

You should start to get a feel for how this helps to smooth latency
spikes – instead of asking “Can I have the next one yet?  How about now?
 Now?” for every individual item, the Consumer simply says
“Let me know when you’ve got more than this number”, and is told in
return how many more entries it can grab.  Because these new entries
have definitely been written (the ring buffer’s sequence has been
updated), and because the only things trying to get to these entries can
only read them and not write to them, this can be done without locks.
 Which is nice.  Not only is it safer and easier to code against, it’s
much faster not to use a lock.

And the added bonus – you can have multiple Consumers reading off the same RingBuffer,
with no need for locks and no need for additional queues to coordinate
between the different threads.  So you can really run your processing in
parallel with the Disruptor coordinating the effort.

The BatchConsumer is an example of consumer code, and if you implement the BatchHandler you can get the BatchConsumer to
do the heavy lifting I’ve outlined above.  Then it’s easy to deal with
the whole batch of entries processed (e.g. from 9-12 above) without
having to fetch each one individually.

EDIT: Note that version 2.0 of the Disruptor uses different names to the ones in this article.  Please see my summary of the changes if you are confused about class names.

文章转自 并发编程网-ifeve.com

时间: 2025-01-02 13:58:36

Dissecting the Disruptor: How do I read from the ring buffer?的相关文章

Dissecting the Disruptor: What’s so special about a ring buffer?

原文地址:http://mechanitis.blogspot.com/2011/06/dissecting-disruptor-whats-so-special.html(因被墙移到墙内) 作者:Trisha Recently we open sourced the LMAX Disruptor, the key to what makes our exchange so fast.  Why did we open source it?  Well, we've realised that

Dissecting the Disruptor: Why it’s so fast (part one) – Locks Are Bad

原文地址:http://mechanitis.blogspot.com/2011/07/dissecting-disruptor-why-its-so-fast.html(因前方有墙,所以我移到墙内) Martin Fowler has written a really good article describing not only the Disruptor, but also how it fits into the architecture at LMAX.  This gives so

Dissecting the Disruptor: Why it’s so fast (part two) – Magic cache line padding

原文地址:http://mechanitis.blogspot.com/2011/07/dissecting-disruptor-why-its-so-fast_22.html(因有墙移到墙内) We mention the phrase Mechanical Sympathy quite a lot, in fact it's even Martin's blog title.  It's about understanding how the underlying hardware oper

Dissecting the Disruptor: Demystifying Memory Barriers

原文地址:http://mechanitis.blogspot.com/2011/08/dissecting-disruptor-why-its-so-fast.html (因有墙,移到墙内) My recent slow-down in posting is because I've been trying to write a post explaining memory barriersand their applicability in the Disruptor. The proble

Dissecting the Disruptor: Writing to the ring buffer

原文地址:http://mechanitis.blogspot.com/2011/07/dissecting-disruptor-writing-to-ring.html(因被墙移到墙内)  作者:Trisha This is the missing piece in the end-to-end view of the Disruptor.  Brace yourselves, it's quite long.  But I decided to keep it in a single blo

并发译文翻译计划(二)

Doug Lea 的文献 Synchronizer Framework  译者:ClarenceAu (已翻译完成,在校对) Fork/Join  译者:Alex(陆续发表中) Java Concurrency Constructs 译者:萧欢(已翻译完成) Cancellation 译者:丁一  (已翻译完成) 以下文章来自:https://code.google.com/p/disruptor/wiki/BlogsAndArticles 如何使用Disruptor What's so spe

如何使用Disruptor(二)如何从Ringbuffer读取

英文原文:http://ifeve.com/dissecting-the-disruptor-how-do-i-read-from-the-ring-buffer/ 作者:Trisha  译者:古圣昌  校对:方腾飞 从上一篇文章中我们都了解了什么是Ring Buffer以及它是如何的特别.但遗憾的是,我还没有讲述如何使用Disruptor向Ring Buffer写数据和从Ring Buffer中读取数据. ConsumerBarrier与消费者 这里我要稍微反过来介绍,因为总的来说读取数据这一

剖析Disruptor:为什么会这么快?(一)锁的缺点

原文:http://ifeve.com/disruptor-locks-are-bad/ 作者:Trisha's  译者:张文灼,潘曦  整理和校对:方腾飞,丁一 Martin Fowler写了一篇非常好的文章,里面不仅提到了Disruptor,而且还解释了Disruptor 如何应用在LMAX的架构里.里面有提及了一些目前没有涉及的概念,但最经常问到的问题是 "Disruptor究竟是什么?". 目前我正准备在回答这个问题,但首先回答"为什么它会这么快?" 这些问题持续出现,但是我不能没有说它

解析Disruptor的依赖关系

原文地址:http://ifeve.com/dissecting-disruptor-wiring-up/ 作者:Trisha   译者:廖涵  校对:方腾飞 现在我已经讲了 RingBuffer​ 本身,如何从它 读取​ 以及如何向它 写入​.从逻辑上来说,下一件要做的事情就是把所有的东西拼装到在一起. 我前面提到过多生产者的情况--他们通过 ProducerBarrier 保证写入操作顺序与可控.我也提到过简单场景下的多消费者数据访问.更多的消费者的场景会变得更加复杂,我们​ 实现了一些聪明