Note that there are some explanatory texts on larger screens.

plurals
  1. POdisruptor performance issues when using two layers of multiple handlers in a pool
    primarykey
    data
    text
    <p>i'm trying to use disruptor to process messages. i need two phases of processing. i.e. two groups of handlers working in a worker pool like this (i guess):</p> <pre><code>disruptor. handleEventsWithWorkerPool( firstPhaseHandlers) .thenHandleEventsWithWorkerPool( secondPhaseHandlers); </code></pre> <p>when using the code above, if i put more than one worker in each group, the performance deteriorates. meaning tons of CPU wasted for the exact same amount of work. <br/> <br/> i tried to tweak with the ring buffer size (which i already saw has an impact on performance) but in this case it didn't help. so am i doing something wrong, or is this a real problem?</p> <hr> <p>i'm attaching a full demo of the issue.</p> <pre><code>import java.util.ArrayList; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicLong; import com.lmax.disruptor.EventFactory; import com.lmax.disruptor.EventTranslatorOneArg; import com.lmax.disruptor.WorkHandler; import com.lmax.disruptor.dsl.Disruptor; final class ValueEvent { private long value; public long getValue() { return value; } public void setValue(long value) { this.value = value; } public final static EventFactory&lt;ValueEvent&gt; EVENT_FACTORY = new EventFactory&lt;ValueEvent&gt;() { public ValueEvent newInstance() { return new ValueEvent(); } }; } class MyWorkHandler implements WorkHandler&lt;ValueEvent&gt; { AtomicLong workDone; public MyWorkHandler (AtomicLong wd) { this.workDone=wd; } public void onEvent(final ValueEvent event) throws Exception { workDone.incrementAndGet(); } } class My2ndPahseWorkHandler implements WorkHandler&lt;ValueEvent&gt; { AtomicLong workDone; public My2ndPahseWorkHandler (AtomicLong wd) { this.workDone=wd; } public void onEvent(final ValueEvent event) throws Exception { workDone.incrementAndGet(); } } class MyEventTranslator implements EventTranslatorOneArg&lt;ValueEvent, Long&gt; { @Override public void translateTo(ValueEvent event, long sequence, Long value) { event.setValue(value); } } public class TwoPhaseDisruptor { static AtomicLong workDone=new AtomicLong(0); @SuppressWarnings("unchecked") public static void main(String[] args) { ExecutorService exec = Executors.newCachedThreadPool(); int numOfHandlersInEachGroup=Integer.parseInt(args[0]); long eventCount=Long.parseLong(args[1]); int ringBufferSize=2 &lt;&lt; (Integer.parseInt(args[2])); Disruptor&lt;ValueEvent&gt; disruptor = new Disruptor&lt;ValueEvent&gt;( ValueEvent.EVENT_FACTORY, ringBufferSize, exec); ArrayList&lt;MyWorkHandler&gt; handlers = new ArrayList&lt;MyWorkHandler&gt;(); for (int i = 0; i &lt; numOfHandlersInEachGroup ; i++) { handlers.add(new MyWorkHandler(workDone)); } ArrayList&lt;My2ndPahseWorkHandler &gt; phase2_handlers = new ArrayList&lt;My2ndPahseWorkHandler &gt;(); for (int i = 0; i &lt; numOfHandlersInEachGroup; i++) { phase2_handlers.add(new My2ndPahseWorkHandler(workDone)); } disruptor .handleEventsWithWorkerPool( handlers.toArray(new WorkHandler[handlers.size()])) .thenHandleEventsWithWorkerPool( phase2_handlers.toArray(new WorkHandler[phase2_handlers.size()])); long s = (System.currentTimeMillis()); disruptor.start(); MyEventTranslator myEventTranslator = new MyEventTranslator(); for (long i = 0; i &lt; eventCount; i++) { disruptor.publishEvent(myEventTranslator, i); } disruptor.shutdown(); exec.shutdown(); System.out.println("time spent "+ (System.currentTimeMillis() - s) + " ms"); System.out.println("amount of work done "+ workDone.get()); } } </code></pre> <p>try running the above example with 1 thread in each group</p> <pre><code>1 100000 7 </code></pre> <p>on my computer it gave </p> <pre><code>time spent 371 ms amount of work done 200000 </code></pre> <p>Then try it with 4 threads in each group</p> <pre><code>4 100000 7 </code></pre> <p>which on my computer gave</p> <pre><code>time spent 9853 ms amount of work done 200000 </code></pre> <p>during the run the CPU is at 100% utilization</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload