[ 
https://issues.apache.org/jira/browse/CAMEL-24779?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Claus Ibsen resolved CAMEL-24779.
---------------------------------
    Resolution: Fixed

> camel-kafka - reduce per-message allocations on the producer, consumer and 
> transform hot paths
> ----------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-24779
>                 URL: https://issues.apache.org/jira/browse/CAMEL-24779
>             Project: Camel
>          Issue Type: Improvement
>          Components: camel-kafka
>            Reporter: Andrea Cosentino
>            Assignee: Andrea Cosentino
>            Priority: Major
>             Fix For: 4.23.0
>
>
> This is a small, behaviour-preserving performance clean-up that bundles three 
> per-message hot-path allocation reductions in camel-kafka. No public API or 
> option changes.
> h3. 1. Producer: redundant callback allocation on the single-message async 
> path
> {{KafkaProducer.process(Exchange, AsyncCallback)}} sends a single record via 
> {{doSend(exchange, record, producerCallBack)}}. Because the key (the 
> exchange) is non-null, {{doSend}} allocates a 
> {{KafkaProducerMetadataCallBack}} *and* a {{DelegatingCallback}} for every 
> message. For the single-message case this is redundant: the parent 
> {{KafkaProducerCallBack}} already sets the exception and the 
> {{CamelKafkaRecordMeta}} header (a {{List<RecordMetadata>}}) on the same 
> exchange. Sending with the parent callback alone removes two short-lived 
> allocations per message and produces an identical {{CamelKafkaRecordMeta}} 
> result. The iterator/batch path is left unchanged (it genuinely needs a 
> per-element metadata callback).
> h3. 2. Consumer: per-record Stream/lambda allocations in header propagation
> {{KafkaRecordProcessor.propagateHeaders}} builds a {{Stream}} + spliterator + 
> two capturing lambdas for every consumed record, and re-resolves 
> {{exchange.getIn()}} per header. Replacing it with a plain enhanced-for loop 
> over {{consumerRecord.headers()}} with a hoisted {{Message}} removes the 
> per-record pipeline and lambda garbage. Behaviour is identical.
> h3. 3. Transforms: ObjectMapper allocated per message
> Six transform classes ({{HoistField}}, {{MaskField}}, {{ExtractField}}, 
> {{ReplaceField}}, {{MessageTimestampRouter}}, {{ValueToKey}}) construct a 
> {{new ObjectMapper()}} on every invocation. {{ObjectMapper}} is expensive to 
> construct and thread-safe once configured; these back the corresponding 
> Kamelet actions and therefore run per message. Reusing a single shared static 
> {{ObjectMapper}} removes the allocation.
> All three changes are behaviour-preserving and covered by existing unit tests 
> plus additions.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to