From 6938d2020bda46bc47273e126274c4b4651fdfb4 Mon Sep 17 00:00:00 2001 From: Matt Welch Date: Tue, 27 Jan 2026 09:47:25 -0800 Subject: [PATCH 1/5] Draft of Kafka BKM guide - Needs review --- software/kafka/README.md | 398 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 398 insertions(+) create mode 100644 software/kafka/README.md diff --git a/software/kafka/README.md b/software/kafka/README.md new file mode 100644 index 0000000..bcb21ea --- /dev/null +++ b/software/kafka/README.md @@ -0,0 +1,398 @@ +This workload tuning guide describes the best known practices to optimize performance on Intel Xeon CPUs when running Apache Kafka. Default configurations may vary across hardware vendors, thus this guide helps provide a set of recommended settings for getting the best performance throughput/latency. This document assumes the user is running Kafka in cloud instances, with a section recommending settings for single node benchmarking at the end of the document. + +# This document is organized with the following topics: +- [Document Nomenclature](#document-nomenclature) +- [Kafka Cluster Topology](#kafka-cluster-topology) + - [Cloud Topology](#cloud-topology) +- [Hardware Configuration Recommendations](#hardware-configuration-recommendations) + - [CPU](#cpu) + - [Memory](#memory) + - [Network](#network) + - [Storage](#storage) +- [Operating System, Kernel, & Software Configuration](#operating-system-kernel--software-configuration) + - [Operating System Settings](#operating-system-settings) + - [Storage Options](#storage-options) + - [Additional Operating System Configuration](#additional-operating-system-configuration) +- [Kafka Cluster-wide Configuration](#kafka-cluster-wide-configuration) + - [Encryption](#encryption) +- [Kafka Controller Configuration](#kafka-controller-configuration) +- [Kafka Broker Configuration](#kafka-broker-configuration) +- [Kafka Producer Configuration](#kafka-producer-configuration) + - [Producer Java Configuration](#producer-java-configuration) + - [Payload](#payload) + - [Topic Configuration](#topic-configuration) +- [Kafka Consumer Configuration](#kafka-consumer-configuration) +- [Measurement Process](#measurement-process) + - [Message Batching](#message-batching) + - [Throughput Sweeps](#throughput-sweeps) + - [Evaluation of Performance and System Health](#evaluation-of-performance-and-system-health) +- [Single Node Configuration](#single-node-configuration) + - [Single-node Topology](#single-node-topology) + - [Single-node Hardware Recommendations](#single-node-hardware-recommendations) + - [Single-node BIOS Configuration Recommendations](#single-node-bios-configuration-recommendations) +- [Example System Startup Script](#example-system-startup-script) + +# Document Nomenclature +This document uses the following terminology: + +- **Client**: Applies only to client systems running the load generator like `kafka-producer-perf-test`, or other benchmarks. Clients can be either Producers or Consumers +- **Server**: Applies only to server systems running the Kafka brokers +- **Single node**: Applies only to systems running Kafka brokers in one socket and producers in another socket for benchmarking in a single bare-metal system +- **Cloud**: Where applicable, notes differences between bare-metal and cloud instances +- **Message or Record**: Used interchangeably, a message or record is a key-value pair stored by Kafka. The value represents the message contents and the key may be empty as is frequently the case in benchmarking Kafka +- **Topic**: In a Kafka cluster, the top-level logical division of data where a message is sent to a specific topic +- **Producer**: In a Kafka cluster, the producer sends messages to the Kafka cluster on a given topic +- **Partition**: Logical subdivision of a topic. Partition count can be set at topic creation or use defaults from Broker configuration. Messages sent to a given partition maintain temporal ordering. The specific partition can be chosen by a producer at send time or can be selected round-robin. +- **Consumer**: In a Kafka cluster, the consumer reads messages from one or more partitions and one or more topics +- **Controller**: The Kafka server that keeps track of cluster members, topics, and partition locations. Controllers can operate as a stand-alone controller or also participate in the Kafka cluster as a broker. +- **Broker**: The Kafka server process which receives messages from producers and stores them until they are read by other brokers or consumers + +# Kafka Cluster Topology +For Kafka 4.0+, a Kafka cluster consists of a set of brokers, at least one controller which may also function as a broker, producers, and consumers. When testing Kafka in a single system, broker and producer performance may be isolated by pinning each process to separate CPUs. In a cloud deployment, each broker resides in its own instance and a single instance can serve as the load generator and run a set of producers. The Kafka workload is an I/O-intensive workload meaning it needs high performing networking and storage subsystems for good performance. Cloud deployments often enable selecting instances with higher performance or configuring select subsystems like storage for higher performance. Where possible, instances should be selected with enhanced networking and storage. + +## Cloud Topology +- One Kafka controller (non-data-broker) running in a small instance, containing at least 4vCPU such as m8i.xlarge. If seeking to build a small cluster, the controller process can run on a broker or on a producer node. +- Four Kafka Brokers running on *4XL systems (16 vCPU) such as m8i.4xlarge. Brokers can scale out to handle higher load on the cluster. +- Scale up Producers running on a large system like m8i.24xlarge or similar; 96vCPU to enable producer scale-up with minimal resource constraints +- Consumers are optional when running a benchmark and can increase the load on the Kafka cluster for a potentially more realistic test. Consumers should typically run a consumer group to evenly distribute the work of reading a topic. Consumer processes should be run on relatively large instances but shouldn't need as many CPU resources as producers. + +### Example Cluster and Scaling + - Controller: one controller process running on the Producer node. Larger clusters with many topics may require additional controllers. + - Brokers: four Kafka brokers, each running on a m8i.4xlarge instances, each with GP3 storage configured for at least 4000 IOPS and 1000 MBps throughput. Additional brokers can be added to scale out the system or brokers may be moved up to larger instances for scale up. + - Producer: Producer processes running on an m8i.24xlarge instance. Increase the count of producers running on this system until the results of the producer performance test reaches the desired SLA. If the producer instance approaches saturation of CPU, storage, or network, additional instances may be utilized to scale out the producers. + +# Hardware Configuration Recommendations +## CPU +If a Kafka cluster has a specific SLA that it must meet, the Broker nodes should not run at 100% CPU utilization at the risk of increasing latency. Since Kafka is so I/O heavy, a broker's storage and network subsystems are often near full utilization with a somewhat underutilized CPU when a Kafka cluster meets the desired SLA. Additionally, a single Kafka broker does not scale well beyond a single NUMA node or socket so care should be taken when sharing those resources among a set of brokers. Finally, newer CPU generations like m8i typically offer higher performance than older nodes like the m5 generation due to CPU enhancements with each generation. For that reason, it's recommended to use instances with at least 8vCPU, 16vCPU preferred. General-purpose Intel-based systems such as m8i.4xlarge offer a good compromise of CPU and memory resources. When benchmarking Kafka, CPU resources should always be monitored to ensure the Kafka process is not limited by available CPU. + +## Memory +The main job of Kafka brokers is to receive and store messages until they're needed. Kafka heavily utilizes the filesystem page cache and its behavior of holding files in free memory until they need to be written back to improve fetch performance for recent messages. For this purpose, any additional free memory, not used by the Kafka JVM, may be utilized as page cache, so additional memory is usually beneficial for Kafka. Additional memory may not improve Kafka's performance on the producer perf test, but can increase the time that older messages are held in cache before writing back to the slower storage medium. + +## Network +In cloud deployments, resources such as network and storage bandwidth can be limited through various mechanisms. When network bandwidth is a limiting resource, many clouds offer network-enhanced instances with higher allotments of network bandwidth. Since Kafka is such a network-intensive workload, it's recommended to use these network-optimized instances when possible. While network-optimized instances may not directly improve Kafka performance, they may increase the robustness of the cluster by removing or minimizing limitations to network performance. Similar to the CPU, network resources should be monitored with telemetry tooling to ensure they are not limiting Kafka performance. + +## Storage +Another potential resource bottleneck in a cloud deployment can be the storage bandwidth of volumes in their default configuration. It's usually possible to increase the I/O operations per second (IOPS) and bandwidth for a volume at creation time. It's recommended that these volumes be configured with at least 4000 IOPS and >=1000 MBps where possible. If storage performance of a single volume that's been configured for maximum throughput is still insufficient to meet an SLA, additional volumes may be attached to brokers or the brokers may be moved to instances with direct-attached NVMes like i7i. As with other system resources, storage telemetry should be monitored to ensure individual devices are not operating beyond their allotted steady-state performance. + +# Operating System, Kernel, & Software Configuration +We recommend using the latest LTS version of Linux OS and kernel with current security and performance patches applied. We describe specific versions of Kafka and Java for testing and compatibility. +- **Kafka version**: 4.2.0 is recommended because it released with an enhancement of the producer performance test that enables a warmup before collecting steady-state statistics. +- **Java version**: Java version 17 or 23 are officially supported by Kafka 4.2.0. Do not use Java 8 because it has been deprecated since Kafka 4.0. Additionally, Java 11 is not recommended due to incomplete support for Kafka Connect and Kafka Server. See [Compatibility](https://kafka.apache.org/41/getting-started/compatibility/) for further information. + +## Operating System Settings +In this section, we describe some Linux operating system settings that can help optimize storage and networking resources to improve Kafka's request latency performance. + +### Operating System Tuning +The Linux adaptive tuning system `tuned` can automatically apply tuning to the operating system based on profiles designed to optimize latency, throughput, power savings, or other goals. For Kafka, we use `tuned` to apply the `latency-performance` profile to improve the response time of Kafka brokers and minimize request latency. +- `# systemctl enable tuned.service; systemctl start tuned.service; tuned-adm profile latency-performance` +Another system-tuning tool used to improve the latency of Kafka is the tool [perfspect](https://github.com/intel/PerfSpect/). Perfspect is a multifunction tool that can be used to gather system metadata and telemetry as well as view and change various system configuration parameters. In the case of Kafka, we use perfspect to apply the `latency-optimized` profile to the Efficiency Latency Control (ELC) system. ELC is only available on Intel Xeon 6 family of CPUs comprising Granite Rapids processors, which can be found in the m8i series of instances. +- `# perfspect config --elc latency-optimized` + +## Storage Options +### Mounting Volumes +Since Kafka is an I/O heavy workload, we want to minimize unnecessary I/O when possible. One way to do this is to use the flags `noatime` and `nodiratime` when mounting volumes to an instance. These flags prevent the filesystem from modifying the access time metadata for files and disks, thereby removing these disk operations. These can be applied as mounting flags in `fstab` or in an ad hoc `mount` command +- `mount -o noatime,nodiratime ` + +### Enable Frequent Write-back to Storage (IMPORTANT!) +High storage latency tends to increase the latency of producer requests as the broker's I/O path becomes congested. When storage subsystems are heavily utilized, write-back events where large quantities of data are sent to storage tend to have higher latency than smaller write-backs. To minimize the volume of data written back to storage at each event, we can decrease the amount of data that will sit in the page cache before a write-back is triggered, known as `vm.dirty_background_bytes`. This will cause the kernel to write-back to storage more frequently as this smaller cache fills up. While this will utilize more of the CPU in the kernel context, this additional utilization reduces write bandwidth and latency which helps clear the I/O path to minimize Kafka's request latency. To choose the optimal value for `dirty_background_bytes`, the user should inspect the output of `iostat` to observe how write latency changes with changes to `dirty_background_bytes`. Absent this telemetry monitoring, setting `dirty_background_bytes` to about 400MB seems to work well for most instances. +- Example: for an m8i.4xlarge, with 16 GB of system memory, 400MB would represent about 2.5% of its 16 GB memory. This can be read and written with `sysctl` or echo'd into the proc fs: + - `sysctl -w vm.dirty_background_bytes=400000000` + - `echo 400000000 > /proc/sys/vm/dirty_background_bytes` + +## Additional Operating System Configuration +Multiple additional settings for the Linux OS can be modified from their defaults to improve Kafka performance. +See the example at [Example System Startup Script](#example-system-startup-script) + +# Kafka Cluster-wide Configuration +Settings in this section apply to all members of the Kafka cluster + +## Encryption +These settings enable TLS encryption, but common stores and passwords are not recommended for production clusters. For more information, see [Encryption and Authentication using SSL](https://kafka.apache.org/41/security/encryption-and-authentication-using-ssl/) +- `ssl.enabled.protocols=TLSv1.2,TLSv1.3` +- Common truststore (copy) between brokers and clients +- Common keystore (copy) between brokers and clients +- Common passwords for `ssl.keystore.password`, `ssl.key.password`, `ssl.truststore.password` +- `ssl.endpoint.identification.algorithm=` (empty for simplified authentication) + +# Kafka Controller Configuration +- At least one Controller running in KRaft mode +- Controller doesn't participate in the cluster to separate the controller workload from the broker message-processing workload + - `process.roles=controller` +- Most other Controller settings can be defaults + +# Kafka Broker Configuration + +- Kafka 4.2.0 (containing warmup patch from KIP-1052), released on XX/YY/ZZ + - [Downloads | Apache Kafka](https://kafka.apache.org/downloads) + - [Release Plan 4.2.0 - Apache Kafka - Apache Software Foundation](https://cwiki.apache.org/confluence/display/KAFKA/Release+Plan+4.2.0) +- **Threads**: Increase network and replica fetcher threads since replication is the slow part of producing a message. Increase socket receive and socket send buffers to minimize dropped packets at the network. + - Example: m8i.4xlarge system with 16 vCPUs + - `num.network.threads=6`: should be less than or equal to half the CPU cores assigned to a broker + - `num.io.threads=8`: should be less than or equal to the count of CPU cores assigned to a broker + - `num.replica.fetchers=2`: increased beyond the default of 2 to improve replication latency + - `socket.receive.buffer.bytes=102400000`: Increased to 100MB from the default of 100kB to improve network performance + - `socket.send.buffer.bytes=102400000`: Increased to 100MB from the default of 100kB to improve network performance + +- **Broker Heap Size**: Set the Java heap to at least 4GB and prevent the heap from growing or shrinking by using the same value for its minimum size: + - `export KAFKA_HEAP_OPTS="-Xms4G -Xmx4G"` +- **Broker Java EXTRA_ARGS**: `"-name kafkaServer -loggc -Xlog:gc* -XX:+PrintFlagsFinal -Xlog:safepoint,gc*,gc+ergo*=trace,gc+age*=trace,gc+phases*=debug:file=$KAFKA_GC_LOG -XX:+AlwaysPreTouch -XX:+UnlockExperimentalVMOptions -XX:G1ReservePercent=2 -XX:G1NewSizePercent=50 -XX:G1MaxNewSizePercent=100` + +# Kafka Producer Configuration + +## Producer Java Configuration +When running Producers on systems with high core counts like an m8i.24xlarge which has 92 vCPUs, it's important to limit each JVM's access to Garbage Collection (GC) threads so they don't each attempt to use all the vCPUs in the system. Producers reading from payloads should also increase their heap size to store the payload. +- Each producer only needs a handful of threads for effective GC, so add this to the producer's Java command line: + - `-XX:ParallelGCThreads=5"` +- Export this environment variable to set the producer to use a 1GB heap and don't grow or shrink the heap: + - `export KAFKA_HEAP_OPTS="-Xms1G -Xmx1G"` + +## Payload +When running the kafka producer performance test, producers may generate messages ad hoc or utilize a payload. Utilizing a payload should reduce the compute load on the producers, which helps ensure that the test is only limited by and measuring the performance of the Kafka cluster, rather than the producers themselves. + +For a production cluster, Kafka will usually use a schema to enforce data structure. These data are serialized by producers into a Kafka Message and sent to the cluster. For benchmarking, it's best if a payload can be assembled from data that at least resembles production data, but a payload of a consistent record size can be useful to assess cluster performance under more controlled conditions. + +Absent production data, data that can be compressed with a compression ratio similar to production data can be a good proxy for a benchmark. A very simple payload file can be constructed with messages delimited by a special character that should not appear in the text such as a pipe character, "`|`". Further information for designing realistic production-quality payloads can be found here [Tips for designing payloads](https://aiven.io/blog/tips-for-designing-payloads). + +## Topic Configuration +Although brokers can set defaults for the following configurations in their server.properties config file, these settings are often set for a given topic when it is created. +- `Replicas=3` - A leader and two followers will each hold a copy of a given partition. As the number of brokers in a cluster increases, the work of replication is spread out across the available brokers. To ensure data integrity, a replication factor of at least 3 should be used. +- `Partitions=8` - Partitions are evenly divided among the available brokers in the cluster. More partitions can increase parallelism and throughput for both producers and consumers. Partitions also consume compute and file resources on Brokers so high partition counts may need additional tuning for good performance. To better understand benchmarking results, the number of partitions can be set as a multiple of the number of brokers to ensure even division of work across the brokers. +- `compression.type=zstd` - zstd usually has the highest throughput of the available compression codecs and is typically recommended for latency-sensitive environments (good balance between compression speed and compression ratio) + +# Kafka Consumer Configuration +While not strictly necessary to measure Kafka producer performance, when testing end-to-end latency of the path Producer -> Kafka Broker -> Consumer, Consumer clients can read data from brokers that contain data on their topic of interest. +It should be noted, however, that the Kafka Consumer test does not spend time processing the messages, so they will not add load mimicking "real consumer latency", but will increase the Fetch and network load on the brokers. +In this case, the work done by Consumers is very similar to the "Fetch" operations done by follower brokers. +Consumers of a given topic that are collaborating on their ingestion of that topic should participate in a Consumer Group so they can evenly share the processing of that topic's data. +The number of Consumers in a group should be tuned to their ability to ingest data from the shared topic. +That is, if a given consumer can ingest more than one partition concurrently without adding latency to the operation, the partitions can outnumber the Consumers. +The number of Consumers in a consumer group attached to a given topic should not exceed the number of partitions in that topic, else the additional consumers in the group will sit idle. +Multiple Consumer processes may share a large system that is configured similarly to a producer instance. + +# Measurement Process +Benchmarking Kafka is typically accomplished with the `kafka-producer-perf-test`. +In this test, the producer sends data to Kafka on a specified topic at a provided rate for a provided number of records. +This test measures the latency of a producer request which is composed of the producer generating a message, sending the message to the brokers, the message being replicated among brokers, and the response from the leader broker to the producer. +At the end of the test, the producer reports resulting statistics comprising average latency and throughput as well as median and tail latencies like p99 which is used for the SLA. +While this default behavior is useful to measure Kafka cluster performance, the resulting statistics of these measurements are often significantly affected by the startup behavior of the Kafka brokers and the Kafka producers. +To get a more accurate measurement of a Kafka cluster's performance during steady-state operation, utilize the `warmup-records` feature added to the `kafka-producer-perf-test` in Kafka 4.2.0. +The `--warmup-records` parameter instructs the producer to classify a fraction of the provided `num-records` as a "warmup" and keep them separate from the steady-state performance which is reported separately from the whole test in the metrics summary statistics lines printed at the end of the test run. +In choosing the test duration, `num-records`, the test should be long enough to get sufficient repeatability in the steady-state p99 measurements. +A warmup allows some time for the broker and producer JVMs to warm up, network connections to be established, and variability from these changes to relax as the cluster reaches steady state. +Often, one minute of warmup is sufficient for these purposes so warmup records should be set based on the producer throughput requested and should be tested iteratively to ensure producer throughput and latency are consistent during steady-state operation. + +## Message Batching +When configuring the producer's sending behavior, two important items stand out to control the flow of data from the producer: batch size and linger. These can be specified in the producer's configuration file `producer.properties` or specified on the command line. +- `linger.ms=5` - Very low linger values can influence batches to be partially filled, reducing overall bandwidth, whereas high linger values can increase latency +- `batch.size=114688` - For our text-based corpus (Shakespeare), larger batches achieve better compression ratio, but can increase batch record-queue-time, since it takes longer to fill the batch at a given rate of message production. These statistics can be viewed in Producer metrics & JMX ouput + +An example producer perf test command line is as follows: +- `$ kafka/bin/kafka-producer-perf-test.sh --topic test-PR78-BR4-PA32-R3 --bootstrap-server 127.0.0.1:9093 --num-records 15000000 --warmup-records 3000000 --payload-file /opt/kafka/kafka-payload.txt --payload-delimiter '\|' --throughput 50000 --print-metrics --producer-props compression.type=zstd acks=all batch.size=114688 linger.ms=5 --command-config /opt/kafka/kafka/config/producer.properties` + +In the command line above, we have a single producer, sending messages from the kafka-payload.txt to a topic named "test-PR78-BR4-PA32-R3". One of the brokers in the cluster is located at the bootstrap-server IP address and listening on port 9093, per its configuration. The producer will send 15M records at a rate of 50k records/second. The first 3M of these records will count as warmup records, where the warmup will last approximately 60 s. This producer will print a summary or internal JMX metrics at the end of the test. The producer will send data with zstd compression, and request acks from all brokers once they have a replica of the message. The producer will wait up to 5 ms to accumulate messages into a batch of size no greater than 112kB, before sending a batch of messages to a single broker. + + +A cluster which is highly loaded may require more time to stabilize its performance + - e.g. at 50k records per second or producer throughput, 3M `warmup-records` and 15M `num-records` will enable a 1 minute warmup, followed by 4 minutes of steady-state + - e.g. at 100k records per second in the same cluster as above, a 2 minute warmup may be required for all producers to successfully establish steady-state flows to the cluster, which would require 2 × 60 × 100k = 12M warmup records to achieve steady-state performance + +Steady-state readiness should be assessed iteratively to ensure that producer throughput and latency during steady-state have stabilized. + + +Finally, while measuring performance of the brokers and producers, tools like `perfspect` should be used to collect a quick system configuration summary with `perfspect report`. + +## Throughput Sweeps +To determine the throughput at which a given cluster hits a desired SLA such as "p99 latency must be less than or equal to 20 ms", we run `kafka-producer-perf-test.sh` with a varied number of producers until the resulting p99 is at or just below the SLA. +This gives us our desired key performance indicator (KPI) of "cluster throughput at a specific latency". +To improve the consistency of the measurement, each producer should send data to the specified topic at the same rate, 50k records/sec here. + +In the figure below, we have the p99 latency measured at various load levels on the cluster. +Each point represents the addition of another producer running at 50k records per second to give the resulting Throughput. +We see that the trend crosses 20 ms at about 350k records/sec so that is our resulting KPI. +``` +Example Latency vs Throughput Curve (p99 Latency) + +p99 Latency +(ms) + 40│ + │ ● + 35│ + │ ● + 30│ + │ ● + 25│ + │ ● + 20│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ●─ ─ ─ ─ ─ ─ ─ ─ + │ + 15│ ● + │ ● + 10│ ● + │ ● + 5│ ● ● + │ + 0└─┴─────┴─────┴─────┴─────┴─────┴─────┴ + 0 100 200 300 400 500 600 + Cluster Throughput (1000 records/sec) + + ● = Measured data point + ─ = SLA threshold line at 20ms + SLA met at ~350k records/sec @ 20ms p99 +``` + +- The `kafka-producer-perf-test.sh` can be run within a scripted for-loop to launch many producers with minimal delay between their start times. This ensures the cluster runs at a consistent load during steady state operation +- Barring some specific use-cases, Producers should typically all send messages to the Kafka cluster at the same rate (e.g. 50,000 records per second) so that they may be evaluated as a group and maintain consistent loading of the cluster +- A "sweep" of producer counts is frequently useful where the test is run at a given load (producer count), then that load is increased in subsequent iterations until the SLA target is reached. Gathering additional data points at loads beyond the SLA ensures the SLA has been met + + + +## Evaluation of Performance and System Health +When benchmarking, we should always pay close attention to the resources used on the system(s) under test (SUT). +Once we've identified our SLA throughput, it's wise to examine the system resources for the test at that throughput to ensure that the performance is not limited by configuration or a particular subsystem. +Many tools are available to monitor the system including [perfspect](https://github.com/intel/PerfSpect) and [SAR](https://www.man7.org/linux/man-pages/man1/sar.1.html) which can both gather metrics from Linux that monitor important system resources such as CPU, storage bandwidth, storage IOPS, storage latency, and network bandwidth. + +One important analysis is to inspect the CPU utilization of the brokers and producers. +If their CPUs are above 80% utilized, there is likely some performance reduction so the cluster admin should consider scaling out the cluster or scaling up the individual systems. +This same analysis should be performed for storage bandwidth, storage IOPS, and network to be sure the systems are not hitting their limits. +With storage, if write latency is high during the run, the cluster should likely scale out or at least scale up the storage of the individual brokers. +For the network, the systems only need to operate under the limits enabled by the instance and consider scaling out or up if at or beyond these limits. + +When operating Kafka in production, it's often undesirable to use multiple additional telemetry tools for fear of affecting performance. +In these cases, Kafka has Java Management Extensions (JMX) metrics that can be passively gathered by Kafka and either logged or displayed on dashboards such as Grafana. Since it's built into Kafka and Java, JMX can offer additional insights into the internal operations of Kafka that cannot otherwise be monitored with external tooling. + +Finally, if users need to better understand the call stacks of Kafka or where Kafka is spending time on CPU, tools such as [flamegraphs](https://www.brendangregg.com/flamegraphs.html) can be extremely useful to gather and understand their call stacks. + +# Single Node Configuration +Here we discuss changes to the configuration and topology of a Kafka cluster when measuring Kafka performance in a single system. + +## Single-node Topology +If running in a single physical system, arrange brokers and producers so they do not interfere with each other's performance. Here are examples of using `numactl` to pin Controllers, Brokers, and Producers to various CPUs in a two-socket, six NUMA node system. +- One Kafka controller (non-data-broker) pinned to socket 0, non-specific CPUs or CPUs not occupied by brokers + - `$ numactl -m "0,1,2" -N "0,1,2" /opt/kafka/kafka/bin/kafka-server-start.sh controller.properties …` +- Four Kafka Brokers on socket 0, pinned to "private" cores + - 4 brokers pinned to NUMA nodes: ( 0 0 1 2 ) + - Example mapping: Start Broker_1 on CPUs 0-15: + - `$ numactl -m 0 -N 0 -C 0-15 /opt/kafka/kafka/bin/kafka-server-start.sh broker0.properties …` +- When running in a lab environment, rather than the cloud, it's preferred to run Producers on a separate system with a very fast network connecting it to the Broker system(s), in which case, pinning producers is not necessary. If only one system is available, Producers should be pinned to a different socket than Brokers if possible to minimize interference in each other's workload. The number of Producers should be scaled up to meet throughput and latency targets. + - Example of pinning producers to Socket 1 in a GNR system with 3 NUMA nodes per socket: + - `$ numactl -m "3,4,5" -N "3,4,5" /opt/kafka/kafka/bin/kafka-producer-perf-test.sh …` + +## Single-node Hardware Recommendations +### Storage +Ensure that each broker has sufficient storage bandwidth by assigning at least one storage drive per broker. Setting up a striped RAID0 array is probably not necessary for drives with at least 1GBps write throughput. While it's possible for brokers to share a single physical drive by using different directories for their log dirs, the user must ensure that drive has sufficient write performance to operate at high throughput without incurring additional latency. + +## Single-node BIOS Configuration Recommendations +If the user has access to the BIOS for a system, here are some parameters that can be changed to improve Kafka performance. +- **SNC**: enabled (GNR 3 NUMA nodes per socket) +- **Hyperthreading**: enabled +- **Latency Optimized mode**: Some Xeon BIOS use this parameter. This setting optimizes for latency vs. power of the memory subsystem which helps latency-sensitive workloads, like Kafka + +### Single-node System Configuration +In contrast to cloud instances, physical servers can often have hundreds of gigabytes of memory installed. In these cases, it's usually more useful to use the setting `vm.dirty_background_bytes` instead of `vm.dirty_background_ratio` since even 1% of 512 GB would be 5 GB which could cause additional latency during write-back. In such a system, even a modest size for `vm.dirty_background_bytes` such as 400MB can enable good performance. +- `vm.dirty_background_bytes=400000000` + +# Example System Startup Script +```bash +############################################ +# recommended kernel settings # +############################################ +ulimit -n 1048576 +ulimit -l unlimited +ulimit -u 32768 +# Disable reclaim mode, disable swap, disable defrag for Transparent +# Hugepages in accordance with DataStax +echo 0 > /proc/sys/vm/zone_reclaim_mode +swapoff –all +echo never | sudo tee /sys/kernel/mm/transparent_hugepage/defrag +############################## +# Network production settings# +############################## +sysctl -w \ +net.ipv4.tcp_keepalive_time=60 \ +net.ipv4.tcp_keepalive_probes=3 \ +net.ipv4.tcp_keepalive_intvl=10 +sysctl -w \ +net.core.rmem_max=16777216 \ +net.core.wmem_max=16777216 \ +net.core.rmem_default=16777216 \ +net.core.wmem_default=16777216 \ +net.core.optmem_max=40960 \ +net.ipv4.tcp_rmem='4096 87380 16777216' \ +net.ipv4.tcp_wmem='4096 65536 16777216' +############################################################### +# Neworking adding 3 additional static IP address on the # +# same network interface for my Cassandra instances # +############################################################### +ifconfig eno1:1 134.134.101.218 up +ifconfig eno1:2 134.134.101.219 up +ifconfig eno1:3 134.134.101.220 up +################################################################ +#setting the system to performance mode for best possible perf # +################################################################ +for CPUFREQ in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor +do + [ -f $CPUFREQ ] || continue + echo -n performance > $CPUFREQ +done +for CPUFREQ in /sys/devices/system/cpu/cpu*/power/energy_perf_bias +do + [ -f $CPUFREQ ] || continue + echo -n performance > $CPUFREQ +done +################################################################## +# Disk Optimizations for storage devices in Database # +# - changing scheduler to none # +# - rotational to zero # +# - changing the read ahead buffer # +################################################################## +touch /var/lock/subsys/local +echo none > /sys/block/nvme1n1/queue/scheduler +echo none > /sys/block/nvme2n1/queue/scheduler +echo none > /sys/block/nvme3n1/queue/scheduler +echo none > /sys/block/nvme4n1/queue/scheduler +echo 0 > /sys/class/block/nvme1n1/queue/rotational +echo 0 > /sys/class/block/nvme2n1/queue/rotational +echo 0 > /sys/class/block/nvme3n1/queue/rotational +echo 0 > /sys/class/block/nvme4n1/queue/rotational +###################################################################### +# Note this change alone will double Cassandra throughput # +# as the Linux default is 128 read_ahead_kb, this can bottleneck the # +# NVME device bandwidth when you have small random requests, like # +# those on cassandra-stress # +###################################################################### +echo 8 > /sys/class/block/nvme1n1/queue/read_ahead_kb +echo 8 > /sys/class/block/nvme2n1/queue/read_ahead_kb +echo 8 > /sys/class/block/nvme3n1/queue/read_ahead_kb +echo 8 > /sys/class/block/nvme4n1/queue/read_ahead_kb + +``` + + + + + \ No newline at end of file From bfc186d8e90cd5db3f82a6c0853db02a06ae527f Mon Sep 17 00:00:00 2001 From: Matt Welch Date: Tue, 3 Feb 2026 13:06:09 -0800 Subject: [PATCH 2/5] Restructure Kafka topology documentation and improve single-node guidance - Separate cloud-agnostic topology guidance from AWS-specific examples - Add "Data Movement in Kafka" section explaining producer write path, consumer read path, and partition leader/follower architecture - Generalize cloud topology section to use vCPU counts instead of AWS-specific instance types - Consolidate AWS deployment details into dedicated example section - Update single-node topology with complete system specifications: * 2 sockets, 192 cores/socket (96 physical + HT) * 6 NUMA nodes (3 per socket, 32 cores/node, SNC enabled) * 3 brokers pinned to dedicated NUMA nodes with 16 logical CPUs each - Add multi-cloud examples (AWS m8i, GCP C4) for Intel Xeon 6 guidance - Remove confusing NUMA notation and provide clear CPU pinning examples --- software/kafka/README.md | 229 ++++++++++++----------- software/kafka/images/Kafka-topology.png | Bin 0 -> 139727 bytes 2 files changed, 115 insertions(+), 114 deletions(-) create mode 100644 software/kafka/images/Kafka-topology.png diff --git a/software/kafka/README.md b/software/kafka/README.md index bcb21ea..f81e1d7 100644 --- a/software/kafka/README.md +++ b/software/kafka/README.md @@ -50,29 +50,78 @@ This document uses the following terminology: # Kafka Cluster Topology For Kafka 4.0+, a Kafka cluster consists of a set of brokers, at least one controller which may also function as a broker, producers, and consumers. When testing Kafka in a single system, broker and producer performance may be isolated by pinning each process to separate CPUs. In a cloud deployment, each broker resides in its own instance and a single instance can serve as the load generator and run a set of producers. The Kafka workload is an I/O-intensive workload meaning it needs high performing networking and storage subsystems for good performance. Cloud deployments often enable selecting instances with higher performance or configuring select subsystems like storage for higher performance. Where possible, instances should be selected with enhanced networking and storage. +## Data Movement in Kafka +Understanding how data flows through a Kafka cluster is essential for optimizing performance. The data movement involves producers, brokers with partition leaders and followers, and consumers. + +### Producer Write Path +When a producer sends a message to Kafka: +1. **Partition Selection**: The producer determines which partition to send the message to. This can be done explicitly by the producer, based on a message key (which is hashed to select a partition), or via round-robin distribution if no key is provided. +2. **Leader Identification**: Each partition has one leader broker and multiple follower brokers (replicas). The producer sends the message to the leader broker for that partition. +3. **Leader Write**: The leader broker receives the message and writes it to its local storage (log segment). +4. **Replication**: The leader then replicates the message to the follower brokers. Follower brokers fetch new data from the leader to maintain an up-to-date copy. +5. **Acknowledgment (acks)**: Depending on the producer's `acks` configuration, the leader responds to the producer: + - `acks=0`: No acknowledgment (fire and forget) + - `acks=1`: Leader acknowledges after writing to its own log + - `acks=all` (or `-1`): Leader waits for all in-sync replicas (ISR) to acknowledge before responding to the producer. This provides the strongest durability guarantee but adds latency as replication must complete. + +The producer request latency is composed of the time to generate the message, send it to the broker, replicate it among brokers in the ISR, and receive the acknowledgment from the leader broker. Replication is often the slowest part of producing a message, particularly when `acks=all` is configured. + +### Consumer Read Path +Consumers read data from Kafka brokers: +1. **Partition Assignment**: Consumers within a consumer group are assigned specific partitions to read from. Each partition is consumed by exactly one consumer within the group, enabling parallel processing. +2. **Fetch Requests**: Consumers send fetch requests to the leader broker of their assigned partitions (though followers can also serve reads in some configurations). +3. **Offset Management**: Consumers track their position in each partition using offsets. The consumer commits offsets periodically to Kafka, allowing it to resume from the last committed position after a restart. +4. **Data Delivery**: The broker returns batches of messages to the consumer, which then processes them according to the application logic. + +### Partition Leaders and Followers +Each partition maintains a **leader** broker and multiple **follower** brokers (replicas). The leader handles all read and write requests for the partition, while followers replicate data from the leader to provide redundancy. If a leader fails, one of the in-sync replicas (ISR) is elected as the new leader, ensuring high availability. The replication factor (typically 3) determines how many copies of each partition exist across the cluster, balancing data integrity with storage and network overhead. + ## Cloud Topology -- One Kafka controller (non-data-broker) running in a small instance, containing at least 4vCPU such as m8i.xlarge. If seeking to build a small cluster, the controller process can run on a broker or on a producer node. -- Four Kafka Brokers running on *4XL systems (16 vCPU) such as m8i.4xlarge. Brokers can scale out to handle higher load on the cluster. -- Scale up Producers running on a large system like m8i.24xlarge or similar; 96vCPU to enable producer scale-up with minimal resource constraints -- Consumers are optional when running a benchmark and can increase the load on the Kafka cluster for a potentially more realistic test. Consumers should typically run a consumer group to evenly distribute the work of reading a topic. Consumer processes should be run on relatively large instances but shouldn't need as many CPU resources as producers. +When deploying Kafka in cloud environments, the cluster components are distributed across separate instances to isolate workloads and enable independent scaling. The following describes the general guidance for each component type and their resource requirements: + +- **Controller**: One Kafka controller (non-data-broker) running in a small instance with at least 4 vCPUs. For smaller clusters, the controller process can colocate on a broker or producer node. Larger clusters with many topics may require additional controllers. +- **Brokers**: Start with four or more Kafka brokers to enable sufficient replication and load distribution. Each broker should run on a medium instance with approximately 16 vCPUs. Brokers can scale out to handle higher load on the cluster by adding more broker instances, or scale up by moving to larger instance sizes with more vCPUs and memory. The broker count should be chosen based on expected throughput, partition count, and desired replication factor. +- **Producers**: Producer processes running on large instances with high vCPU counts (80-100 vCPUs) to enable producer scale-up with minimal resource constraints. Increase the count of producer processes running on these systems until the cluster reaches the desired SLA. If producer instances approach saturation of CPU, storage, or network resources, additional instances may be added to scale out the producer capacity. +- **Consumers**: Consumers are optional when running benchmarks but increase the load on the Kafka cluster for more realistic testing. Consumer processes should run in a consumer group to evenly distribute the work of reading a topic. Consumer instances should be relatively large but typically don't need as many CPU resources as producer instances. + +For all instance types, select configurations with enhanced networking and high-performance storage where available, as Kafka is an I/O-intensive workload that benefits significantly from these optimizations. + +Figure 1: Kafka Topology +![Kafka Topology](images/Kafka-topology.png) -### Example Cluster and Scaling - - Controller: one controller process running on the Producer node. Larger clusters with many topics may require additional controllers. - - Brokers: four Kafka brokers, each running on a m8i.4xlarge instances, each with GP3 storage configured for at least 4000 IOPS and 1000 MBps throughput. Additional brokers can be added to scale out the system or brokers may be moved up to larger instances for scale up. - - Producer: Producer processes running on an m8i.24xlarge instance. Increase the count of producers running on this system until the results of the producer performance test reaches the desired SLA. If the producer instance approaches saturation of CPU, storage, or network, additional instances may be utilized to scale out the producers. +## Example: AWS Deployment +This section provides a concrete example of the cloud topology using AWS infrastructure and instance types. + +- **Controller**: One controller process running on the producer node (or a dedicated m8i.xlarge instance for larger clusters). Larger clusters with many topics may require additional controllers. +- **Brokers**: Four Kafka brokers, each running on m8i.4xlarge instances (16 vCPUs, Intel Xeon-based), each with GP3 storage configured for at least 4000 IOPS and 1000 MBps throughput. Additional brokers can be added to scale out the system, or brokers may be moved up to larger instances (e.g., m8i.8xlarge or m8i.16xlarge) for scale up. +- **Producers**: Producer processes running on an m8i.24xlarge instance (96 vCPUs). Increase the count of producer processes running on this system until the results of the producer performance test reach the desired SLA. If the producer instance approaches saturation of CPU, storage, or network, additional m8i.24xlarge instances may be added to scale out the producers. +- **Consumers**: Consumer processes can run on m8i.12xlarge or similar instances, which provide sufficient resources without the full scale of producer instances. + +The m8i instance family uses Intel Xeon 6 (Granite Rapids) processors. For cost optimization, newer generation instances (m8i) typically provide better performance than older generations (m7i, m6i, m5) due to CPU improvements with each generation. # Hardware Configuration Recommendations ## CPU -If a Kafka cluster has a specific SLA that it must meet, the Broker nodes should not run at 100% CPU utilization at the risk of increasing latency. Since Kafka is so I/O heavy, a broker's storage and network subsystems are often near full utilization with a somewhat underutilized CPU when a Kafka cluster meets the desired SLA. Additionally, a single Kafka broker does not scale well beyond a single NUMA node or socket so care should be taken when sharing those resources among a set of brokers. Finally, newer CPU generations like m8i typically offer higher performance than older nodes like the m5 generation due to CPU enhancements with each generation. For that reason, it's recommended to use instances with at least 8vCPU, 16vCPU preferred. General-purpose Intel-based systems such as m8i.4xlarge offer a good compromise of CPU and memory resources. When benchmarking Kafka, CPU resources should always be monitored to ensure the Kafka process is not limited by available CPU. +If a Kafka cluster has a specific SLA that it must meet, the Broker nodes should not run at 100% CPU utilization at the risk of increasing latency. Since Kafka is so I/O heavy, a broker's storage and network subsystems are often near full utilization with a somewhat underutilized CPU when a Kafka cluster meets the desired SLA. Additionally, a single Kafka broker does not scale well beyond a single NUMA node or socket so care should be taken when sharing those resources among a set of brokers. + +Finally, newer CPU generations typically offer higher performance than older generations due to CPU enhancements with each generation. For that reason, it's recommended to use instances with at least 8vCPU, 16vCPU preferred. General-purpose Intel-based systems with 16 vCPUs offer a good compromise of CPU and memory resources for broker workloads. On AWS, instances like m8i.4xlarge (Intel Xeon 6) provide better performance than older generations like m7i or m5. Use the latest generation CPU when possible because newer CPU generations have new instructions that can improve encryption and compression performance. + +When benchmarking Kafka, CPU resources should always be monitored to ensure the Kafka process is not limited by available CPU. ## Memory -The main job of Kafka brokers is to receive and store messages until they're needed. Kafka heavily utilizes the filesystem page cache and its behavior of holding files in free memory until they need to be written back to improve fetch performance for recent messages. For this purpose, any additional free memory, not used by the Kafka JVM, may be utilized as page cache, so additional memory is usually beneficial for Kafka. Additional memory may not improve Kafka's performance on the producer perf test, but can increase the time that older messages are held in cache before writing back to the slower storage medium. +The main job of Kafka brokers is to receive and store messages until they're needed. Kafka heavily utilizes the filesystem page cache and its behavior of holding files in free memory until they need to be written back to improve fetch performance for recent messages. For this purpose, any additional free memory, not used by the Kafka JVM, may be utilized as page cache, so additional memory is usually beneficial for Kafka. ## Network -In cloud deployments, resources such as network and storage bandwidth can be limited through various mechanisms. When network bandwidth is a limiting resource, many clouds offer network-enhanced instances with higher allotments of network bandwidth. Since Kafka is such a network-intensive workload, it's recommended to use these network-optimized instances when possible. While network-optimized instances may not directly improve Kafka performance, they may increase the robustness of the cluster by removing or minimizing limitations to network performance. Similar to the CPU, network resources should be monitored with telemetry tooling to ensure they are not limiting Kafka performance. +In cloud deployments, resources such as network and storage bandwidth are limited based on the instance used. +When network bandwidth is a limiting resource, many clouds offer network-enhanced instances with higher allotments of network bandwidth. +Since Kafka is such a network-intensive workload, it's recommended to use these network-optimized instances when possible. +Similar to the CPU, network resources should be monitored with telemetry tooling to ensure they are not limiting Kafka performance. +If any members of the cluster are close to their Network throughput limits, depending on which instances are limited, consider scaling out the cluster by adding more brokers or producers to distribute the network load. ## Storage -Another potential resource bottleneck in a cloud deployment can be the storage bandwidth of volumes in their default configuration. It's usually possible to increase the I/O operations per second (IOPS) and bandwidth for a volume at creation time. It's recommended that these volumes be configured with at least 4000 IOPS and >=1000 MBps where possible. If storage performance of a single volume that's been configured for maximum throughput is still insufficient to meet an SLA, additional volumes may be attached to brokers or the brokers may be moved to instances with direct-attached NVMes like i7i. As with other system resources, storage telemetry should be monitored to ensure individual devices are not operating beyond their allotted steady-state performance. +Another potential resource bottleneck in a cloud deployment can be the storage bandwidth of volumes in their default configuration. It's usually possible to increase the I/O operations per second (IOPS) and bandwidth for a volume at creation time. It's recommended that these volumes be configured with high IOPS and throughput where possible. If storage performance of a single volume that's been configured for maximum throughput is still insufficient to meet an SLA, additional volumes may be attached to brokers or the brokers may be moved to instances with direct-attached NVMes. +As with other system resources, storage telemetry should be monitored to ensure individual devices are not operating beyond their allotted steady-state performance. +Scaling storage when hitting instance resource limits is somewhat more flexible than scaling the network because, in addition to the possibility of growing the cluster capacity with scale-out of additional brokers, additional storage volumes can usually be added to brokers to increase their storage capacity. +An alternative to adding volumes would be to scale up the brokers to systems with direct-attached NVMe's that enable high-performance storage. # Operating System, Kernel, & Software Configuration We recommend using the latest LTS version of Linux OS and kernel with current security and performance patches applied. We describe specific versions of Kafka and Java for testing and compatibility. @@ -85,7 +134,7 @@ In this section, we describe some Linux operating system settings that can help ### Operating System Tuning The Linux adaptive tuning system `tuned` can automatically apply tuning to the operating system based on profiles designed to optimize latency, throughput, power savings, or other goals. For Kafka, we use `tuned` to apply the `latency-performance` profile to improve the response time of Kafka brokers and minimize request latency. - `# systemctl enable tuned.service; systemctl start tuned.service; tuned-adm profile latency-performance` -Another system-tuning tool used to improve the latency of Kafka is the tool [perfspect](https://github.com/intel/PerfSpect/). Perfspect is a multifunction tool that can be used to gather system metadata and telemetry as well as view and change various system configuration parameters. In the case of Kafka, we use perfspect to apply the `latency-optimized` profile to the Efficiency Latency Control (ELC) system. ELC is only available on Intel Xeon 6 family of CPUs comprising Granite Rapids processors, which can be found in the m8i series of instances. +Another system-tuning tool used to improve the latency of Kafka is the tool [perfspect](https://github.com/intel/PerfSpect/). Perfspect is a multifunction tool that can be used to gather system metadata and telemetry as well as view and change various system configuration parameters. In the case of Kafka, we use perfspect to apply the `latency-optimized` profile to the Efficiency Latency Control (ELC) system. ELC is only available on Intel Xeon 6 family of CPUs comprising Granite Rapids processors (e.g., AWS m8i series, GCP C4 series). - `# perfspect config --elc latency-optimized` ## Storage Options @@ -93,9 +142,13 @@ Another system-tuning tool used to improve the latency of Kafka is the tool [per Since Kafka is an I/O heavy workload, we want to minimize unnecessary I/O when possible. One way to do this is to use the flags `noatime` and `nodiratime` when mounting volumes to an instance. These flags prevent the filesystem from modifying the access time metadata for files and disks, thereby removing these disk operations. These can be applied as mounting flags in `fstab` or in an ad hoc `mount` command - `mount -o noatime,nodiratime ` -### Enable Frequent Write-back to Storage (IMPORTANT!) -High storage latency tends to increase the latency of producer requests as the broker's I/O path becomes congested. When storage subsystems are heavily utilized, write-back events where large quantities of data are sent to storage tend to have higher latency than smaller write-backs. To minimize the volume of data written back to storage at each event, we can decrease the amount of data that will sit in the page cache before a write-back is triggered, known as `vm.dirty_background_bytes`. This will cause the kernel to write-back to storage more frequently as this smaller cache fills up. While this will utilize more of the CPU in the kernel context, this additional utilization reduces write bandwidth and latency which helps clear the I/O path to minimize Kafka's request latency. To choose the optimal value for `dirty_background_bytes`, the user should inspect the output of `iostat` to observe how write latency changes with changes to `dirty_background_bytes`. Absent this telemetry monitoring, setting `dirty_background_bytes` to about 400MB seems to work well for most instances. -- Example: for an m8i.4xlarge, with 16 GB of system memory, 400MB would represent about 2.5% of its 16 GB memory. This can be read and written with `sysctl` or echo'd into the proc fs: +### Enable Frequent Write-back to Storage + +High storage latency tends to increase the latency of producer requests as the broker's I/O path becomes congested. + +Under normal operation, Kafka constantly receives data and writes it to storage. +When storage subsystems are heavily utilized, write-back events where large quantities of data are sent to storage tend to have higher latency than smaller write-backs. To minimize the volume of data written back to storage at each event, we can decrease the amount of data that will sit in the page cache before a write-back is triggered, known as `vm.dirty_background_bytes`. This will cause the kernel to write-back to storage more frequently as this smaller cache fills up. While this will utilize more of the CPU in the kernel context, reduces spikes in write bandwidth, IOPS, and disk latency which helps to improve Kafka's request latency. To choose a good value for `dirty_background_bytes`, the user should inspect the output of `iostat` to observe how write latency, bandwidth, and IOPS change. +- Example: for an instance, with 16 GB of system memory, 400MB would represent about 2.5% of its 16 GB memory. This can be read and written with `sysctl` or echo'd into the proc fs: - `sysctl -w vm.dirty_background_bytes=400000000` - `echo 400000000 > /proc/sys/vm/dirty_background_bytes` @@ -126,7 +179,7 @@ These settings enable TLS encryption, but common stores and passwords are not re - [Downloads | Apache Kafka](https://kafka.apache.org/downloads) - [Release Plan 4.2.0 - Apache Kafka - Apache Software Foundation](https://cwiki.apache.org/confluence/display/KAFKA/Release+Plan+4.2.0) - **Threads**: Increase network and replica fetcher threads since replication is the slow part of producing a message. Increase socket receive and socket send buffers to minimize dropped packets at the network. - - Example: m8i.4xlarge system with 16 vCPUs + - Example: Cloud instance with 16 vCPUs - `num.network.threads=6`: should be less than or equal to half the CPU cores assigned to a broker - `num.io.threads=8`: should be less than or equal to the count of CPU cores assigned to a broker - `num.replica.fetchers=2`: increased beyond the default of 2 to improve replication latency @@ -140,29 +193,28 @@ These settings enable TLS encryption, but common stores and passwords are not re # Kafka Producer Configuration ## Producer Java Configuration -When running Producers on systems with high core counts like an m8i.24xlarge which has 92 vCPUs, it's important to limit each JVM's access to Garbage Collection (GC) threads so they don't each attempt to use all the vCPUs in the system. Producers reading from payloads should also increase their heap size to store the payload. +When running concurrent Producers on systems with high core counts like an instance with 92 vCPUs, it's important to limit each JVM's access to Garbage Collection (GC) threads so they don't each attempt to use all the vCPUs in the system. Producers reading from payloads should also increase their heap size to store the payload. - Each producer only needs a handful of threads for effective GC, so add this to the producer's Java command line: - `-XX:ParallelGCThreads=5"` - Export this environment variable to set the producer to use a 1GB heap and don't grow or shrink the heap: - `export KAFKA_HEAP_OPTS="-Xms1G -Xmx1G"` ## Payload -When running the kafka producer performance test, producers may generate messages ad hoc or utilize a payload. Utilizing a payload should reduce the compute load on the producers, which helps ensure that the test is only limited by and measuring the performance of the Kafka cluster, rather than the producers themselves. +When running the kafka producer performance test, producers may generate random messages on demand or read messages from a payload. Utilizing a payload improves producer efficiency. This ensures that the test is only limited by the performance of the Kafka cluster, rather than the producers themselves. -For a production cluster, Kafka will usually use a schema to enforce data structure. These data are serialized by producers into a Kafka Message and sent to the cluster. For benchmarking, it's best if a payload can be assembled from data that at least resembles production data, but a payload of a consistent record size can be useful to assess cluster performance under more controlled conditions. +For a production cluster, Kafka will usually use a schema to enforce data structure. These data are serialized by producers into a Kafka Message and sent to the cluster. For benchmarking, it's best if a payload can be assembled from data that resembles production data, but a payload of a consistent record size can be useful to assess cluster performance under more controlled conditions. Absent production data, data that can be compressed with a compression ratio similar to production data can be a good proxy for a benchmark. A very simple payload file can be constructed with messages delimited by a special character that should not appear in the text such as a pipe character, "`|`". Further information for designing realistic production-quality payloads can be found here [Tips for designing payloads](https://aiven.io/blog/tips-for-designing-payloads). ## Topic Configuration -Although brokers can set defaults for the following configurations in their server.properties config file, these settings are often set for a given topic when it is created. +Although brokers can set defaults for the following configurations in their `server.properties` config file, these settings are often set for a given topic when it is created. - `Replicas=3` - A leader and two followers will each hold a copy of a given partition. As the number of brokers in a cluster increases, the work of replication is spread out across the available brokers. To ensure data integrity, a replication factor of at least 3 should be used. - `Partitions=8` - Partitions are evenly divided among the available brokers in the cluster. More partitions can increase parallelism and throughput for both producers and consumers. Partitions also consume compute and file resources on Brokers so high partition counts may need additional tuning for good performance. To better understand benchmarking results, the number of partitions can be set as a multiple of the number of brokers to ensure even division of work across the brokers. -- `compression.type=zstd` - zstd usually has the highest throughput of the available compression codecs and is typically recommended for latency-sensitive environments (good balance between compression speed and compression ratio) +- `compression.type=zstd` - zstd usually has the highest throughput of the available compression options and is typically recommended for latency-sensitive environments (good balance between compression speed and compression ratio) # Kafka Consumer Configuration While not strictly necessary to measure Kafka producer performance, when testing end-to-end latency of the path Producer -> Kafka Broker -> Consumer, Consumer clients can read data from brokers that contain data on their topic of interest. It should be noted, however, that the Kafka Consumer test does not spend time processing the messages, so they will not add load mimicking "real consumer latency", but will increase the Fetch and network load on the brokers. -In this case, the work done by Consumers is very similar to the "Fetch" operations done by follower brokers. Consumers of a given topic that are collaborating on their ingestion of that topic should participate in a Consumer Group so they can evenly share the processing of that topic's data. The number of Consumers in a group should be tuned to their ability to ingest data from the shared topic. That is, if a given consumer can ingest more than one partition concurrently without adding latency to the operation, the partitions can outnumber the Consumers. @@ -174,41 +226,29 @@ Benchmarking Kafka is typically accomplished with the `kafka-producer-perf-test` In this test, the producer sends data to Kafka on a specified topic at a provided rate for a provided number of records. This test measures the latency of a producer request which is composed of the producer generating a message, sending the message to the brokers, the message being replicated among brokers, and the response from the leader broker to the producer. At the end of the test, the producer reports resulting statistics comprising average latency and throughput as well as median and tail latencies like p99 which is used for the SLA. -While this default behavior is useful to measure Kafka cluster performance, the resulting statistics of these measurements are often significantly affected by the startup behavior of the Kafka brokers and the Kafka producers. To get a more accurate measurement of a Kafka cluster's performance during steady-state operation, utilize the `warmup-records` feature added to the `kafka-producer-perf-test` in Kafka 4.2.0. The `--warmup-records` parameter instructs the producer to classify a fraction of the provided `num-records` as a "warmup" and keep them separate from the steady-state performance which is reported separately from the whole test in the metrics summary statistics lines printed at the end of the test run. In choosing the test duration, `num-records`, the test should be long enough to get sufficient repeatability in the steady-state p99 measurements. -A warmup allows some time for the broker and producer JVMs to warm up, network connections to be established, and variability from these changes to relax as the cluster reaches steady state. +A warmup allows some time for the broker and producer JVMs to warm up, network connections to be established, and variability from these changes to reach equilibrium as the cluster reaches steady state. Often, one minute of warmup is sufficient for these purposes so warmup records should be set based on the producer throughput requested and should be tested iteratively to ensure producer throughput and latency are consistent during steady-state operation. ## Message Batching When configuring the producer's sending behavior, two important items stand out to control the flow of data from the producer: batch size and linger. These can be specified in the producer's configuration file `producer.properties` or specified on the command line. -- `linger.ms=5` - Very low linger values can influence batches to be partially filled, reducing overall bandwidth, whereas high linger values can increase latency +- `linger.ms=5` - Very low linger values can influence batches to be partially filled, reducing overall bandwidth, whereas high linger values can increase request latency - `batch.size=114688` - For our text-based corpus (Shakespeare), larger batches achieve better compression ratio, but can increase batch record-queue-time, since it takes longer to fill the batch at a given rate of message production. These statistics can be viewed in Producer metrics & JMX ouput An example producer perf test command line is as follows: - `$ kafka/bin/kafka-producer-perf-test.sh --topic test-PR78-BR4-PA32-R3 --bootstrap-server 127.0.0.1:9093 --num-records 15000000 --warmup-records 3000000 --payload-file /opt/kafka/kafka-payload.txt --payload-delimiter '\|' --throughput 50000 --print-metrics --producer-props compression.type=zstd acks=all batch.size=114688 linger.ms=5 --command-config /opt/kafka/kafka/config/producer.properties` -In the command line above, we have a single producer, sending messages from the kafka-payload.txt to a topic named "test-PR78-BR4-PA32-R3". One of the brokers in the cluster is located at the bootstrap-server IP address and listening on port 9093, per its configuration. The producer will send 15M records at a rate of 50k records/second. The first 3M of these records will count as warmup records, where the warmup will last approximately 60 s. This producer will print a summary or internal JMX metrics at the end of the test. The producer will send data with zstd compression, and request acks from all brokers once they have a replica of the message. The producer will wait up to 5 ms to accumulate messages into a batch of size no greater than 112kB, before sending a batch of messages to a single broker. - - -A cluster which is highly loaded may require more time to stabilize its performance - - e.g. at 50k records per second or producer throughput, 3M `warmup-records` and 15M `num-records` will enable a 1 minute warmup, followed by 4 minutes of steady-state - - e.g. at 100k records per second in the same cluster as above, a 2 minute warmup may be required for all producers to successfully establish steady-state flows to the cluster, which would require 2 × 60 × 100k = 12M warmup records to achieve steady-state performance - -Steady-state readiness should be assessed iteratively to ensure that producer throughput and latency during steady-state have stabilized. - - -Finally, while measuring performance of the brokers and producers, tools like `perfspect` should be used to collect a quick system configuration summary with `perfspect report`. +In the command line above, we have a single producer, sending messages from the kafka-payload.txt to a topic named "test-PR78-BR4-PA32-R3". One of the brokers in the cluster is located at the bootstrap-server IP address and listening on port 9093, per its configuration. The producer will send 15M records at a rate of 50k records/second. The first 3M of these records will count as warmup records, where the warmup will last approximately 60 s. This producer will print a summary or internal JMX metrics at the end of the test. The producer will send data with zstd compression, and request acks from all brokers once they have a replica of the message. The producer will wait up to 5 ms to accumulate messages into a batch of size no greater than 112kB, before sending a batch of messages to a single broker. Monitor the output of the producer performance test to determine if a longer warmup is needed. ## Throughput Sweeps -To determine the throughput at which a given cluster hits a desired SLA such as "p99 latency must be less than or equal to 20 ms", we run `kafka-producer-perf-test.sh` with a varied number of producers until the resulting p99 is at or just below the SLA. -This gives us our desired key performance indicator (KPI) of "cluster throughput at a specific latency". -To improve the consistency of the measurement, each producer should send data to the specified topic at the same rate, 50k records/sec here. +To determine the throughput at which a given cluster hits a desired SLA such as "p99 latency must be less than or equal to 20 ms", we run `kafka-producer-perf-test.sh` with an increasing number of producers until the resulting p99 is at or just below the SLA. +This gives us our desired key performance indicator (KPI) of "cluster throughput at SLA". +To improve the consistency of the measurement, each producer should send data to the specified topic at the same rate, 50k records/sec in this example. -In the figure below, we have the p99 latency measured at various load levels on the cluster. -Each point represents the addition of another producer running at 50k records per second to give the resulting Throughput. -We see that the trend crosses 20 ms at about 350k records/sec so that is our resulting KPI. +In the figure below, we have the results of a sweep as described above, showing p99 latency for each load level. +The figure shows cluster throughput at 20 ms SLA to be approximately 350k records/sec. ``` Example Latency vs Throughput Curve (p99 Latency) @@ -236,60 +276,64 @@ p99 Latency ● = Measured data point ─ = SLA threshold line at 20ms - SLA met at ~350k records/sec @ 20ms p99 ``` -- The `kafka-producer-perf-test.sh` can be run within a scripted for-loop to launch many producers with minimal delay between their start times. This ensures the cluster runs at a consistent load during steady state operation -- Barring some specific use-cases, Producers should typically all send messages to the Kafka cluster at the same rate (e.g. 50,000 records per second) so that they may be evaluated as a group and maintain consistent loading of the cluster -- A "sweep" of producer counts is frequently useful where the test is run at a given load (producer count), then that load is increased in subsequent iterations until the SLA target is reached. Gathering additional data points at loads beyond the SLA ensures the SLA has been met - - - ## Evaluation of Performance and System Health When benchmarking, we should always pay close attention to the resources used on the system(s) under test (SUT). -Once we've identified our SLA throughput, it's wise to examine the system resources for the test at that throughput to ensure that the performance is not limited by configuration or a particular subsystem. +Once we've identified our SLA throughput, it's wise to examine the system resources for the test at that throughput to ensure that the performance is not limited by configuration or a particular system resources. Many tools are available to monitor the system including [perfspect](https://github.com/intel/PerfSpect) and [SAR](https://www.man7.org/linux/man-pages/man1/sar.1.html) which can both gather metrics from Linux that monitor important system resources such as CPU, storage bandwidth, storage IOPS, storage latency, and network bandwidth. -One important analysis is to inspect the CPU utilization of the brokers and producers. +One important analysis is to inspect the CPU utilization of the brokers and producers to ensure that high CPU utilization is not limiting producer scaling or broker performance. If their CPUs are above 80% utilized, there is likely some performance reduction so the cluster admin should consider scaling out the cluster or scaling up the individual systems. + This same analysis should be performed for storage bandwidth, storage IOPS, and network to be sure the systems are not hitting their limits. -With storage, if write latency is high during the run, the cluster should likely scale out or at least scale up the storage of the individual brokers. -For the network, the systems only need to operate under the limits enabled by the instance and consider scaling out or up if at or beyond these limits. +For the network, the systems only need to operate under the limits allowed by the instance and consider scaling out or up if at or beyond these limits. When operating Kafka in production, it's often undesirable to use multiple additional telemetry tools for fear of affecting performance. -In these cases, Kafka has Java Management Extensions (JMX) metrics that can be passively gathered by Kafka and either logged or displayed on dashboards such as Grafana. Since it's built into Kafka and Java, JMX can offer additional insights into the internal operations of Kafka that cannot otherwise be monitored with external tooling. +In these cases, Kafka has Java Management Extensions (JMX) metrics that can be passively gathered by Kafka and either logged or displayed on dashboards such as Grafana. +Since it's built into Kafka and Java, JMX can offer additional insights into the internal operations of Kafka that cannot otherwise be monitored with external tooling. +To enable JMX on a Kafka process, add the `JMX_PORT` variable to the environment of the process. +For more info on JMX see (Monitoring)[https://kafka.apache.org/42/operations/monitoring/] Finally, if users need to better understand the call stacks of Kafka or where Kafka is spending time on CPU, tools such as [flamegraphs](https://www.brendangregg.com/flamegraphs.html) can be extremely useful to gather and understand their call stacks. +To enable flamegraphs for any Java process including Kafka, add the following arguments to the Java command line for each process: +- `-XX:+PreserveFramePointer -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints` # Single Node Configuration -Here we discuss changes to the configuration and topology of a Kafka cluster when measuring Kafka performance in a single system. +Here we discuss changes to the configuration and topology of a Kafka cluster when measuring Kafka performance of brokers running in a single system. ## Single-node Topology -If running in a single physical system, arrange brokers and producers so they do not interfere with each other's performance. Here are examples of using `numactl` to pin Controllers, Brokers, and Producers to various CPUs in a two-socket, six NUMA node system. -- One Kafka controller (non-data-broker) pinned to socket 0, non-specific CPUs or CPUs not occupied by brokers +If running in a single physical system, arrange brokers so that they don't interfere with each other's performance as much as possible. The following examples demonstrate pinning Controllers and Brokers to specific CPUs in a two-socket system with 192 cores per socket (96 physical cores with hyperthreading enabled) and six NUMA nodes (3 NUMA nodes per socket, 32 physical cores per NUMA node), using Sub-NUMA Clustering (SNC) enabled. + +With hyperthreading enabled, each physical core has two logical threads. The thread numbering follows the pattern where low-order CPUs (0-95) represent the first hyperthread of each physical core on socket 0, and high-order CPUs (192-287) represent the second hyperthread of the same physical cores. + +- **Controller**: One Kafka controller (non-data-broker) pinned to socket 0, using non-specific CPUs not occupied by brokers - `$ numactl -m "0,1,2" -N "0,1,2" /opt/kafka/kafka/bin/kafka-server-start.sh controller.properties …` -- Four Kafka Brokers on socket 0, pinned to "private" cores - - 4 brokers pinned to NUMA nodes: ( 0 0 1 2 ) - - Example mapping: Start Broker_1 on CPUs 0-15: - - `$ numactl -m 0 -N 0 -C 0-15 /opt/kafka/kafka/bin/kafka-server-start.sh broker0.properties …` -- When running in a lab environment, rather than the cloud, it's preferred to run Producers on a separate system with a very fast network connecting it to the Broker system(s), in which case, pinning producers is not necessary. If only one system is available, Producers should be pinned to a different socket than Brokers if possible to minimize interference in each other's workload. The number of Producers should be scaled up to meet throughput and latency targets. - - Example of pinning producers to Socket 1 in a GNR system with 3 NUMA nodes per socket: - - `$ numactl -m "3,4,5" -N "3,4,5" /opt/kafka/kafka/bin/kafka-producer-perf-test.sh …` + +- **Brokers**: Three Kafka brokers on socket 0, each pinned to a subset of cores within a dedicated NUMA node with private cores to minimize interference. Each broker uses 8 physical cores with both hyperthreads (16 logical CPUs total): + - Broker 0 on NUMA node 0 (CPUs 0-7,192-199): `$ numactl -m 0 -N 0 -C 0-7,192-199 /opt/kafka/kafka/bin/kafka-server-start.sh broker0.properties …` + - Broker 1 on NUMA node 1 (CPUs 32-39,224-231): `$ numactl -m 1 -N 1 -C 32-39,224-231 /opt/kafka/kafka/bin/kafka-server-start.sh broker1.properties …` + - Broker 2 on NUMA node 2 (CPUs 64-71,256-263): `$ numactl -m 2 -N 2 -C 64-71,256-263 /opt/kafka/kafka/bin/kafka-server-start.sh broker2.properties …` + +This configuration assigns 16 logical CPUs (8 physical cores × 2 hyperthreads) per broker, ensuring each broker has exclusive access to its assigned CPU cores and local memory within its NUMA node, which minimizes memory access latency and maximizes performance. ## Single-node Hardware Recommendations ### Storage -Ensure that each broker has sufficient storage bandwidth by assigning at least one storage drive per broker. Setting up a striped RAID0 array is probably not necessary for drives with at least 1GBps write throughput. While it's possible for brokers to share a single physical drive by using different directories for their log dirs, the user must ensure that drive has sufficient write performance to operate at high throughput without incurring additional latency. +Ensure that each broker has sufficient storage bandwidth by assigning at least one storage drive per broker. While it's possible for brokers to share a single physical drive by using different directories for their log dirs, it is not recommended. ## Single-node BIOS Configuration Recommendations If the user has access to the BIOS for a system, here are some parameters that can be changed to improve Kafka performance. -- **SNC**: enabled (GNR 3 NUMA nodes per socket) +- **Sub-NUMA CLustering (SNC)**: enabls multiple NUMA nodes so each broker can run on its own NUMA node - **Hyperthreading**: enabled -- **Latency Optimized mode**: Some Xeon BIOS use this parameter. This setting optimizes for latency vs. power of the memory subsystem which helps latency-sensitive workloads, like Kafka +- **Latency Optimized mode**: Some Xeon BIOS use this parameter. This setting optimizes for latency vs. power of the memory subsystem which helps latency-sensitive workloads ### Single-node System Configuration In contrast to cloud instances, physical servers can often have hundreds of gigabytes of memory installed. In these cases, it's usually more useful to use the setting `vm.dirty_background_bytes` instead of `vm.dirty_background_ratio` since even 1% of 512 GB would be 5 GB which could cause additional latency during write-back. In such a system, even a modest size for `vm.dirty_background_bytes` such as 400MB can enable good performance. - `vm.dirty_background_bytes=400000000` +TODO: Delete the above after figuring out if it's per-numa node +dirty_background_bytes affects all sockets and nodes in the system + # Example System Startup Script ```bash ############################################ @@ -318,13 +362,7 @@ net.core.wmem_default=16777216 \ net.core.optmem_max=40960 \ net.ipv4.tcp_rmem='4096 87380 16777216' \ net.ipv4.tcp_wmem='4096 65536 16777216' -############################################################### -# Neworking adding 3 additional static IP address on the # -# same network interface for my Cassandra instances # -############################################################### -ifconfig eno1:1 134.134.101.218 up -ifconfig eno1:2 134.134.101.219 up -ifconfig eno1:3 134.134.101.220 up + ################################################################ #setting the system to performance mode for best possible perf # ################################################################ @@ -339,7 +377,7 @@ do echo -n performance > $CPUFREQ done ################################################################## -# Disk Optimizations for storage devices in Database # +# Disk Optimizations for Kafka storage devices # # - changing scheduler to none # # - rotational to zero # # - changing the read ahead buffer # @@ -353,46 +391,9 @@ echo 0 > /sys/class/block/nvme1n1/queue/rotational echo 0 > /sys/class/block/nvme2n1/queue/rotational echo 0 > /sys/class/block/nvme3n1/queue/rotational echo 0 > /sys/class/block/nvme4n1/queue/rotational -###################################################################### -# Note this change alone will double Cassandra throughput # -# as the Linux default is 128 read_ahead_kb, this can bottleneck the # -# NVME device bandwidth when you have small random requests, like # -# those on cassandra-stress # -###################################################################### echo 8 > /sys/class/block/nvme1n1/queue/read_ahead_kb echo 8 > /sys/class/block/nvme2n1/queue/read_ahead_kb echo 8 > /sys/class/block/nvme3n1/queue/read_ahead_kb echo 8 > /sys/class/block/nvme4n1/queue/read_ahead_kb -``` - - - - - \ No newline at end of file +``` \ No newline at end of file diff --git a/software/kafka/images/Kafka-topology.png b/software/kafka/images/Kafka-topology.png new file mode 100644 index 0000000000000000000000000000000000000000..821ea88283121581eebf2eb9025988703339576d GIT binary patch literal 139727 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 Date: Wed, 11 Feb 2026 11:30:28 -0800 Subject: [PATCH 3/5] docs(kafka): Update BKM for Kafka 4.2 RC usage - Add disclaimer note about 4.2 RC testing - Update all version references to specify "release candidate (RC)" - Remove TODO placeholders and update docs URLs to Kafka 4.1 - Clarify vm.dirty_background_bytes applies system-wide --- software/kafka/README.md | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/software/kafka/README.md b/software/kafka/README.md index f81e1d7..094354a 100644 --- a/software/kafka/README.md +++ b/software/kafka/README.md @@ -1,4 +1,6 @@ -This workload tuning guide describes the best known practices to optimize performance on Intel Xeon CPUs when running Apache Kafka. Default configurations may vary across hardware vendors, thus this guide helps provide a set of recommended settings for getting the best performance throughput/latency. This document assumes the user is running Kafka in cloud instances, with a section recommending settings for single node benchmarking at the end of the document. +This workload tuning guide describes the best known practices to optimize performance on Intel Xeon CPUs when running Apache Kafka. Default configurations may vary across hardware vendors, thus this guide helps provide a set of recommended settings for getting the best performance throughput/latency. This document assumes the user is running Kafka in cloud instances, with a section recommending settings for single node benchmarking at the end of the document. + +> **Note**: This guide is based on testing with Kafka 4.2.0 release candidate (RC). Users should verify configurations and features with the final Kafka 4.2.0 release when available, as some behaviors or settings may change. # This document is organized with the following topics: - [Document Nomenclature](#document-nomenclature) @@ -125,8 +127,8 @@ An alternative to adding volumes would be to scale up the brokers to systems wit # Operating System, Kernel, & Software Configuration We recommend using the latest LTS version of Linux OS and kernel with current security and performance patches applied. We describe specific versions of Kafka and Java for testing and compatibility. -- **Kafka version**: 4.2.0 is recommended because it released with an enhancement of the producer performance test that enables a warmup before collecting steady-state statistics. -- **Java version**: Java version 17 or 23 are officially supported by Kafka 4.2.0. Do not use Java 8 because it has been deprecated since Kafka 4.0. Additionally, Java 11 is not recommended due to incomplete support for Kafka Connect and Kafka Server. See [Compatibility](https://kafka.apache.org/41/getting-started/compatibility/) for further information. +- **Kafka version**: Kafka 4.2.0 release candidate (RC) is used for this guide as it includes an enhancement to the producer performance test that enables a warmup period before collecting steady-state statistics. +- **Java version**: Java version 17 or 23 are officially supported by Kafka 4.2.0 RC. Do not use Java 8 because it has been deprecated since Kafka 4.0. Additionally, Java 11 is not recommended due to incomplete support for Kafka Connect and Kafka Server. See [Compatibility](https://kafka.apache.org/41/getting-started/compatibility/) for further information. ## Operating System Settings In this section, we describe some Linux operating system settings that can help optimize storage and networking resources to improve Kafka's request latency performance. @@ -160,7 +162,7 @@ See the example at [Example System Startup Script](#example-system-startup-scrip Settings in this section apply to all members of the Kafka cluster ## Encryption -These settings enable TLS encryption, but common stores and passwords are not recommended for production clusters. For more information, see [Encryption and Authentication using SSL](https://kafka.apache.org/41/security/encryption-and-authentication-using-ssl/) +These settings enable TLS encryption, but common stores and passwords are not recommended for production clusters. For more information, see [Encryption and Authentication using SSL](https://kafka.apache.org/41/security/encryption-and-authentication-using-ssl/) - `ssl.enabled.protocols=TLSv1.2,TLSv1.3` - Common truststore (copy) between brokers and clients - Common keystore (copy) between brokers and clients @@ -174,10 +176,8 @@ These settings enable TLS encryption, but common stores and passwords are not re - Most other Controller settings can be defaults # Kafka Broker Configuration - -- Kafka 4.2.0 (containing warmup patch from KIP-1052), released on XX/YY/ZZ +- Kafka 4.2.0 release candidate (containing warmup patch from KIP-1052) - [Downloads | Apache Kafka](https://kafka.apache.org/downloads) - - [Release Plan 4.2.0 - Apache Kafka - Apache Software Foundation](https://cwiki.apache.org/confluence/display/KAFKA/Release+Plan+4.2.0) - **Threads**: Increase network and replica fetcher threads since replication is the slow part of producing a message. Increase socket receive and socket send buffers to minimize dropped packets at the network. - Example: Cloud instance with 16 vCPUs - `num.network.threads=6`: should be less than or equal to half the CPU cores assigned to a broker @@ -226,7 +226,7 @@ Benchmarking Kafka is typically accomplished with the `kafka-producer-perf-test` In this test, the producer sends data to Kafka on a specified topic at a provided rate for a provided number of records. This test measures the latency of a producer request which is composed of the producer generating a message, sending the message to the brokers, the message being replicated among brokers, and the response from the leader broker to the producer. At the end of the test, the producer reports resulting statistics comprising average latency and throughput as well as median and tail latencies like p99 which is used for the SLA. -To get a more accurate measurement of a Kafka cluster's performance during steady-state operation, utilize the `warmup-records` feature added to the `kafka-producer-perf-test` in Kafka 4.2.0. +To get a more accurate measurement of a Kafka cluster's performance during steady-state operation, utilize the `warmup-records` feature available in the `kafka-producer-perf-test` in Kafka 4.2.0 RC. The `--warmup-records` parameter instructs the producer to classify a fraction of the provided `num-records` as a "warmup" and keep them separate from the steady-state performance which is reported separately from the whole test in the metrics summary statistics lines printed at the end of the test run. In choosing the test duration, `num-records`, the test should be long enough to get sufficient repeatability in the steady-state p99 measurements. A warmup allows some time for the broker and producer JVMs to warm up, network connections to be established, and variability from these changes to reach equilibrium as the cluster reaches steady state. @@ -293,7 +293,7 @@ When operating Kafka in production, it's often undesirable to use multiple addit In these cases, Kafka has Java Management Extensions (JMX) metrics that can be passively gathered by Kafka and either logged or displayed on dashboards such as Grafana. Since it's built into Kafka and Java, JMX can offer additional insights into the internal operations of Kafka that cannot otherwise be monitored with external tooling. To enable JMX on a Kafka process, add the `JMX_PORT` variable to the environment of the process. -For more info on JMX see (Monitoring)[https://kafka.apache.org/42/operations/monitoring/] +For more info on JMX see [Monitoring](https://kafka.apache.org/41/operations/monitoring/) Finally, if users need to better understand the call stacks of Kafka or where Kafka is spending time on CPU, tools such as [flamegraphs](https://www.brendangregg.com/flamegraphs.html) can be extremely useful to gather and understand their call stacks. To enable flamegraphs for any Java process including Kafka, add the following arguments to the Java command line for each process: @@ -328,12 +328,9 @@ If the user has access to the BIOS for a system, here are some parameters that c - **Latency Optimized mode**: Some Xeon BIOS use this parameter. This setting optimizes for latency vs. power of the memory subsystem which helps latency-sensitive workloads ### Single-node System Configuration -In contrast to cloud instances, physical servers can often have hundreds of gigabytes of memory installed. In these cases, it's usually more useful to use the setting `vm.dirty_background_bytes` instead of `vm.dirty_background_ratio` since even 1% of 512 GB would be 5 GB which could cause additional latency during write-back. In such a system, even a modest size for `vm.dirty_background_bytes` such as 400MB can enable good performance. +In contrast to cloud instances, physical servers can often have hundreds of gigabytes of memory installed. In these cases, it's usually more useful to use the setting `vm.dirty_background_bytes` instead of `vm.dirty_background_ratio` since even 1% of 512 GB would be 5 GB which could cause additional latency during write-back. In such a system, even a modest size for `vm.dirty_background_bytes` such as 400MB can enable good performance. Note that `vm.dirty_background_bytes` affects all sockets and nodes in the system. - `vm.dirty_background_bytes=400000000` -TODO: Delete the above after figuring out if it's per-numa node -dirty_background_bytes affects all sockets and nodes in the system - # Example System Startup Script ```bash ############################################ From 9d5e204d8262e773f6bad61123bb6b4b7329607f Mon Sep 17 00:00:00 2001 From: Matt Welch Date: Thu, 12 Feb 2026 16:34:12 -0800 Subject: [PATCH 4/5] Add link to Kafka under main README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index dad0b27..2022869 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ We aim to provide a dynamic resource where users can find the latest optimizatio - [Java](software/java/README.md) - [Spark](software/spark/README.md) - [MySQL & PostgreSQL](software/mysql-postgresql/README.md) + - [Kafka](software/kafka/README.md) - Workloads - [Cassandra Stress](workloads/cassandra-stress/README.md) - [HPC](workloads/hpc/README.md) From f41eaeaec8d2a55dde60b8add2d1eeffbda37d63 Mon Sep 17 00:00:00 2001 From: Matt Welch Date: Tue, 17 Feb 2026 09:30:48 -0800 Subject: [PATCH 5/5] fix: typos --- software/kafka/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/software/kafka/README.md b/software/kafka/README.md index 094354a..d90426e 100644 --- a/software/kafka/README.md +++ b/software/kafka/README.md @@ -123,7 +123,7 @@ If any members of the cluster are close to their Network throughput limits, depe Another potential resource bottleneck in a cloud deployment can be the storage bandwidth of volumes in their default configuration. It's usually possible to increase the I/O operations per second (IOPS) and bandwidth for a volume at creation time. It's recommended that these volumes be configured with high IOPS and throughput where possible. If storage performance of a single volume that's been configured for maximum throughput is still insufficient to meet an SLA, additional volumes may be attached to brokers or the brokers may be moved to instances with direct-attached NVMes. As with other system resources, storage telemetry should be monitored to ensure individual devices are not operating beyond their allotted steady-state performance. Scaling storage when hitting instance resource limits is somewhat more flexible than scaling the network because, in addition to the possibility of growing the cluster capacity with scale-out of additional brokers, additional storage volumes can usually be added to brokers to increase their storage capacity. -An alternative to adding volumes would be to scale up the brokers to systems with direct-attached NVMe's that enable high-performance storage. +An alternative to adding volumes would be to scale up the brokers to systems with direct-attached NVMes that enable high-performance storage. # Operating System, Kernel, & Software Configuration We recommend using the latest LTS version of Linux OS and kernel with current security and performance patches applied. We describe specific versions of Kafka and Java for testing and compatibility. @@ -182,7 +182,7 @@ These settings enable TLS encryption, but common stores and passwords are not re - Example: Cloud instance with 16 vCPUs - `num.network.threads=6`: should be less than or equal to half the CPU cores assigned to a broker - `num.io.threads=8`: should be less than or equal to the count of CPU cores assigned to a broker - - `num.replica.fetchers=2`: increased beyond the default of 2 to improve replication latency + - `num.replica.fetchers=2`: increased beyond the default of 1 to improve replication latency - `socket.receive.buffer.bytes=102400000`: Increased to 100MB from the default of 100kB to improve network performance - `socket.send.buffer.bytes=102400000`: Increased to 100MB from the default of 100kB to improve network performance @@ -323,7 +323,7 @@ Ensure that each broker has sufficient storage bandwidth by assigning at least o ## Single-node BIOS Configuration Recommendations If the user has access to the BIOS for a system, here are some parameters that can be changed to improve Kafka performance. -- **Sub-NUMA CLustering (SNC)**: enabls multiple NUMA nodes so each broker can run on its own NUMA node +- **Sub-NUMA Clustering (SNC)**: enables multiple NUMA nodes so each broker can run on its own NUMA node - **Hyperthreading**: enabled - **Latency Optimized mode**: Some Xeon BIOS use this parameter. This setting optimizes for latency vs. power of the memory subsystem which helps latency-sensitive workloads @@ -361,7 +361,7 @@ net.ipv4.tcp_rmem='4096 87380 16777216' \ net.ipv4.tcp_wmem='4096 65536 16777216' ################################################################ -#setting the system to performance mode for best possible perf # +# setting the system to performance mode for best possible perf # ################################################################ for CPUFREQ in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor do