camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > Camel 2.x Speed optimizations
Date Mon, 20 Jun 2011 10:42:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2042/9/1/_/styles/combined.css?spaceKey=CAMEL&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/CAMEL/Camel+2.x+Speed+optimizations">Camel
2.x Speed optimizations</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~davsclaus">Claus
Ibsen</a>
    </h4>
        <br/>
                         <h4>Changes (3)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>h3. Reduce Exchange copying
<br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">*DONE
in Camel 2.8* <br></td></tr>
            <tr><td class="diff-unchanged" >The first issue to address is to reduce
the need for copying exchanges. <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>h4. Only when redelivering
<br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">*DONE
in Camel 2.8* <br></td></tr>
            <tr><td class="diff-unchanged" >A defensive copy of the Exchange is
*only* needed when Camel does redelivery using its [Error Handler] features. So the goal is
to move <br>the defensive copy from the Pipeline to {{org.apache.camel.processor.RedeliveryErrorHandler}}.
As this error handler is the base for doing redelivery within Camel itself. Then the speed
gain is when users do not use this error handler at all. <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>h4. Only copy Message and
not Exchange <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">*WONT
FIX* <br></td></tr>
            <tr><td class="diff-unchanged" >Another goal is to only copy the IN
message as its the *input* to a processor, and where the processor can mutate it. So instead
of copying the entire Exchange we can reduce it to only copying the IN message. This enforces
the convention that Exchange properties will not be copied. <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h2><a name="Camel2.xSpeedoptimizations-Camel2.xSpeedoptimizations"></a>Camel
2.x Speed optimizations</h2>

<p>This design page is about how to optimize and make Camel 2.x more performant. </p>

<h3><a name="Camel2.xSpeedoptimizations-Sourcecode"></a>Source code</h3>
<p>We got an experiment branch at Apache at: <tt><a href="https://svn.apache.org/repos/asf/camel/sandbox/tuning-experiment/"
class="external-link" rel="nofollow">https://svn.apache.org/repos/asf/camel/sandbox/tuning-experiment/</a></tt></p>

<p>You are welcome to checkout the branch and help along with tuning. </p>

<h3><a name="Camel2.xSpeedoptimizations-ReduceExchangecopying"></a>Reduce
Exchange copying</h3>
<p><b>DONE in Camel 2.8</b><br/>
The first issue to address is to reduce the need for copying exchanges.</p>

<p>Currently Camel does defensive copying of the current Exchange being routed. This
happens in <tt>org.apache.camel.processor.Pipeline</tt>.<br/>
This hotspot should be reduced as the Pipeline should <b>not</b> do defensive
copy of the Exchange.</p>

<h4><a name="Camel2.xSpeedoptimizations-MessageFacade"></a>Message Facade</h4>
<p>We should introduce a message facade to detect mutations to messages.<br/>
The code is in <tt>org.apache.camel.impl.CopyOnWriteMessageFacade</tt>.</p>

<h4><a name="Camel2.xSpeedoptimizations-INshouldbeimmutable"></a>IN should
be immutable</h4>
<p>If IN is immutable it makes redelivery much easier as we just pass in IN yet again.<br/>
The code is in <tt>org.apache.camel.impl.ImmutableMessage</tt>.</p>

<h4><a name="Camel2.xSpeedoptimizations-Onlywhenredelivering"></a>Only when
redelivering</h4>
<p><b>DONE in Camel 2.8</b><br/>
A defensive copy of the Exchange is <b>only</b> needed when Camel does redelivery
using its <a href="/confluence/display/CAMEL/Error+Handler" title="Error Handler">Error
Handler</a> features. So the goal is to move<br/>
the defensive copy from the Pipeline to <tt>org.apache.camel.processor.RedeliveryErrorHandler</tt>.
As this error handler is the base for doing redelivery within Camel itself. Then the speed
gain is when users do not use this error handler at all.</p>

<h4><a name="Camel2.xSpeedoptimizations-OptimizeRedeliveryErrorHandler"></a>Optimize
RedeliveryErrorHandler</h4>
<p>A second goal is to implement logic in RedeliveryErrorHandler to only do defensive
copying if a redelivery is possible. End users need to explicit enable redelivery in Camel.
By implementing logic if a redelivery is ever possible or not we can reduce the copying even
further.</p>

<h4><a name="Camel2.xSpeedoptimizations-OnlycopyMessageandnotExchange"></a>Only
copy Message and not Exchange</h4>
<p><b>WONT FIX</b><br/>
Another goal is to only copy the IN message as its the <b>input</b> to a processor,
and where the processor can mutate it. So instead of copying the entire Exchange we can reduce
it to only copying the IN message. This enforces the convention that Exchange properties will
not be copied.</p>

<h4><a name="Camel2.xSpeedoptimizations-NotmanyprocessorscanmutateINmessage"></a>Not
many processors can mutate IN message</h4>
<p>Many of the processors (eg transports, protocols etc.) do not mutate/modify the IN
message so we can leverage this fact that a copy is only needed in some situations. For instance
the File producer do not mutate the IN message so we do not need to copy it even if we do
redelivery.</p>

<p>Logic can be build in to cater for this. For instance:</p>
<ul class="alternate" type="square">
	<li>Some interface to indicate whether a Processor can mutate or not.</li>
	<li>.process can mutate (you get access to the entire Exchange)</li>
	<li>.bean can mutate (only in some situations)</li>
	<li>we can allow end users to indicate whether they mutate the exchange or not</li>
	<li>we can let end users set a flag on the exchange if it was mutated</li>
	<li>we can add some proxy if getBody/setBody getHeader/setHeader was invoked on IN
message to indicate if it was possible to mutate it</li>
</ul>


<p>We dont have to go all the way, by having just all the Camel component/processors
being able to indicate whether they can mutate or not is a big win.<br/>
The optimizations of bean/process can be secondary objective as it can be a bit overkill and
complex.</p>

<h4><a name="Camel2.xSpeedoptimizations-Coarsegrainedperformancecounters"></a>Coarse
grained performance counters</h4>
<p><b>DONE in Camel 2.1</b><br/>
The JMX performance counters is very fine grained today. We should reduce this to only do
performance counts for the entire route instead of spanning every single node in the route
path.</p>

<p>And we should add options for JMX to enable/disable this as you may not want to grab
these details but only want JMX to be able to manage producers, consumers, routes and endpoints
etc.</p>

<h4><a name="Camel2.xSpeedoptimizations-Channel"></a>Channel</h4>
<p>Optimize Channel to be able to skip doing hoops through interceptors that is not
needed such as: JMX, StreamCaching, Error Handler etc. when these are configured as disabled
to be more strait through.</p>

<h4><a name="Camel2.xSpeedoptimizations-UsingYourKitprofiler"></a>Using
YourKit profiler</h4>
<p>We should use a profiler to aid find hotspots to optimize. </p>

<p>Claus used YourKit to find the following hot spots:</p>
<ul class="alternate" type="square">
	<li>type converter to String could be greatly optimized as it tended to go over fallback
converters</li>
	<li>recipient list with only 1 element could be avoid to not use a Scanner as creating
a Scanner costs performance</li>
</ul>


<h4><a name="Camel2.xSpeedoptimizations-Performancetests"></a>Performance
tests</h4>
<p>We should have some performance tests we can run and see what we archive.</p>

<p>A very crude experiment from Claus showed 2x gain by avoiding doing excessive exchange
copies in the <tt>RoutePerformanceTest</tt> unit test by modifying the <tt>Pipeline</tt>
processor to not do a copy of the Exchange.</p>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/Camel+2.x+Speed+optimizations">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=122183&revisedVersion=8&originalVersion=7">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/Camel+2.x+Speed+optimizations?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message