Tuning Apache Kafka® Connectors for Flink| Confidential | 2022-07-10
Tuning Apache Kafka®
Connectors for Flink
A story:
Test -> Production
migration frustration
Same: Business logic, Code.
Different: Data, Load, Clusters and database configs.
Job Status: FAILED
Reason:
...org.apache.kafka.common.errors.RecordTooLargeException:
The message is [X] bytes when serialized which is larger than [Y]
Job Status: FAILED
Step 1. Fix in Flink Sink config:
'properties.max.request.size' >=
MAX_MESSAGE_SIZE_IN_BYTES
Job Status: FAILED
Reason:
...org.apache.kafka.common.errors.RecordTooLargeException:
The request included a message larger than the max message
size the server will accept.
Job Status: RUNNING
Reason:
...org.apache.kafka.common.errors.RecordTooLargeException:
The request included a message larger than the max message
size the server will accept.
Step 2. Fix in Kafka topic config:
'max.message.bytes' >= MAX_MESSAGE_SIZE_IN_BYTES
logs/TOPIC_NAME_AND_PARTITION_NUMBER/
Kafka segments on a disk
logs/TOPIC_NAME_AND_PARTITION_NUMBER/
Messages inside segments
logs/TOPIC_NAME_AND_PARTITION_NUMBER/
50 times smaller segment
logs/TOPIC_NAME_AND_PARTITION_NUMBER/
50 times smaller segment
logs/TOPIC_NAME_AND_PARTITION_NUMBER/
Increased max.message.bytes
Job Status: FAILED
Reason:
...org.apache.kafka.common.errors.RecordBatchTooLargeException:
The request included message batch larger than the configured
segment size on the server.
Job Status: RUNNING
Fix in Kafka topic config:
'segment.bytes' >= MAX_MESSAGE_SIZE_IN_BYTES
Reason:
...org.apache.kafka.common.errors.RecordBatchTooLargeException:
The request included message batch larger than the configured
segment size on the server.
Impact on Flink Source
Performance improvement:
'properties.request.timeout.ms' > 30 Sec
Job Status: RUNNING (No progress)
Reason:
...INFO...org.apache.kafka.clients.FetchSessionHandler - Error
sending fetch request to node 5:
...org.apache.kafka.common.errors.DisconnectException: null
Big batches
Big batches
Big batches
Big batches
Big batches
Performance improvement:
'properties.properties.batch.size' >=
X * MAX_MESSAGE_SIZE_IN_BYTES
Job Status: RUNNING (No progress)
Reason:
...WARN...org.apache.kafka.clients.producer.internals.Sender - Got
error produce response in correlation id 137 on topic-partition
response-0, splitting and retrying (2147483647 attempts left).
Error: MESSAGE_TOO_LARGE
Job Status: RUNNING
Fix in Kafka topic config:
'max.message.bytes' >= X * MAX_MESSAGE_SIZE_IN_BYTES
Reason:
...WARN...org.apache.kafka.clients.producer.internals.Sender - Got
error produce response in correlation id 137 on topic-partition
response-0, splitting and retrying (2147483647 attempts left).
Error: MESSAGE_TOO_LARGE
Job Status: RUNNING (No progress)
Reason:
...WARN...org.apache.kafka.clients.producer.internals.Sender - Got
error produce response in correlation id 137 on topic-partition
response-0, splitting and retrying (2147483647 attempts left).
Error: MESSAGE_TOO_LARGE
Job Status: FINISHED
Fix in Flink Sink Config:
'properties.compression.type' = 'snappy' ['gzip', 'lz4', 'zstd']
Reason:
...WARN...org.apache.kafka.clients.producer.internals.Sender - Got
error produce response in correlation id 137 on topic-partition
response-0, splitting and retrying (2147483647 attempts left).
Error: MESSAGE_TOO_LARGE
Batch compression
Pros:
● Save disk space on Kafka
● The bigger batch, the better compression
● Fewer chances to get a timeout
Batch compression
Cons:
● Every consumer has to decompress messages
● A Flink Sink task runs slower
● Compression uses additional memory (~ 315 MB of JVM heap
per 5000 partitions)
Impact on Flink Source
Job Status: RUNNING
Performance improvement:
'properties.max.partition.fetch.bytes' >=
X * MAX_MESSAGE_SIZE_IN_BYTES
High load and spikes
High load and spikes
properties.batch.size + properties.linger.ms
Impact on Flink Source
properties.fetch.min.bytes + properties.fetch.max.wait.ms
High load
properties.max.in.flight.requests.per.connection = 1
High load
properties.max.in.flight.requests.per.connection = 3
High load
properties.max.in.flight.requests.per.connection = 3
High load
properties.max.in.flight.requests.per.connection = 3
High load
Warning
To keep records order in partition with retry > 0 (Default)
'max.in.flight.requests.per.connection' = 1 AND
‘enable.idempotence’ = False
OR
'max.in.flight.requests.per.connection' = 5(Default) AND
‘acks’ = ‘all’ AND ‘enable.idempotence’ = True
Custom Partitioner
Why custom partitioner?
org.apache.kafka.clients.producer.internals.DefaultPartitioner
Records for specific topic with null keys and no
assigned partition will be sent to the same
partition until the batch is ready to be sent.
When a new batch is created, a new partition is
chosen
Why custom partitioner?
Why custom partitioner?
Why custom partitioner?
org.apache.kafka.clients.producer.internals.DefaultPartitioner
If no partition is specified but a key is present,
choose a partition based on a hash of the key
Why custom partitioner?
Why custom partitioner?
Why custom partitioner?
Why custom partitioner?
Custom partitioner apply
// Input: sortedWeights = {'DE': 20, 'FR': 11, 'DK': 2, 'CZ': 1}, nPartitions = 3
totalSum = sum(sortedWeights.values()); accSum = 0;
keysSumWeights = sortedWeights.forEach((k, v) ->
{ accSum += v; return (k, accSum /totalSum) }
// {"DE":0.588, 'FR': 0.912, 'DK': 0.97, 'CZ': 1}
fraction = 1.0 / nPartitions; partition = 1; partitionsDistribution = {}
for k, v in keysSumWeights
partitionDistribution[k] = min(partition, nPartitions) - 1
if v >= partition * fraction
partition += 1
return partitionsDistribution
Custom partitioner apply
Custom partitioner apply
Generate: 'DE', 'GB', 'FI', 'ES', 'NO'
DE - individual
GB - individual
FI, ES, NO - shared
Custom partitioner apply
Generate: 'DE', 'GB', 'FI','ES', 'NO'
DE - individual
GB - individual
FI, ES, NO - shared
Custom partitioner apply
Custom partitioner apply
Custom partitioner apply
Flink partitioner vs Kafka partitioner
Flink Partitioner
Class org.apache.flink.streaming.connectors.kafka.partitioner.FlinkKafkaPartitioner
.option("sink.partitioner", "org.myorg.quickstart.FlinkWeightedPartitioner")
Kafka Partitioner
Class org.apache.kafka.clients.producer.Partitioner
.option("properties.partitioner.class", "org.apache.kafka.clients.producer.RoundRobinPartitioner")
❏ A custom partitioner could improve the performance of a Flink
Source.
❏ Add custom ConsumerPartitionAssignor in
‘properties.partition.assignment.strategy’ if necessary.
Impact on Flink Source/Kafka Consumer
Summary
● Enormous messages
● Group records to big batches
● Spikes, High load
● Custom partitions
Adapt Apache Kafka Sink/Source according
to business needs and data load
Ask me about Flink and Kafka!
Olena Babenko
Senior Software Engineer
olena@aiven.io

Tuning Apache Kafka Connectors for Flink.pptx

Editor's Notes

  • #4 Kafka optimised for small but frequent records, to work with a big record, some tuning is needed.
  • #7 Sometimes changing such a property require a Kafka knowledge, not only Flink tuning
  • #8 Why Kafka do that? Why is it so restrictive?
  • #29 Batch size high, but not too high
  • #39 Some edge cases it might be uneven. Batch.size too high.
  • #45 If there is time
  • #47 Generate only DE, GB, FI, NO ES
  • #48 Generate only DE, GB, FI, NO ES
  • #55 Thank you for your attention. If you want to ask questions later, don't hesitate to contact me in linked in, or write . You can ask questions now.