Skip to content

AxonOps — AI-Native Control Plane for Open Source Data Platforms

Kafka Cluster Topology

Cluster topology design for fault tolerance, performance, and operational efficiency.


DatacenterRack 1Rack 2Rack 3NetworkBroker 1Broker 4Broker 2Broker 5Broker 3Broker 6Top-of-RackSwitchesSpineSwitchesNetwork bandwidth should besized for replication traffic

Rack awareness ensures partition replicas are distributed across failure domains to survive rack-level failures.

# server.properties - set on each broker
broker.rack=rack-1

With rack awareness enabled, Kafka distributes replicas across racks:

TopicPartitionReplica 1Replica 2Replica 3
orders0Broker 1 (rack-1)Broker 2 (rack-2)Broker 3 (rack-3)
orders1Broker 2 (rack-2)Broker 3 (rack-3)Broker 4 (rack-1)
orders2Broker 3 (rack-3)Broker 1 (rack-1)Broker 5 (rack-2)

Consumers can prefer reading from replicas in the same rack to reduce cross-rack traffic.

consumer.properties
client.rack=rack-1
# broker configuration (rack-aware replica selection)
replica.selector.class=org.apache.kafka.common.replica.RackAwareReplicaSelector

Follower fetching

client.rack enables clients to prefer local replicas when supported (Kafka 2.4+). If no matching replica is available, consumers read from the leader.


Traffic TypeSizing
ProducePeak produce throughput × number of brokers receiving
ReplicationPeak produce throughput × (replication factor - 1)
ConsumePeak consume throughput × consumer fan-out
Inter-brokerMetadata + coordination overhead
Required bandwidth = (P × (RF - 1)) + C + P
Where:
P = Peak produce throughput (MB/s)
RF = Replication factor
C = Peak consume throughput (MB/s)

Example:

  • Peak produce: 500 MB/s
  • Replication factor: 3
  • Peak consume: 1000 MB/s (2x fanout)
  • Required: (500 × 3) + 1000 = 2500 MB/s = 20 Gbps
Leaf-Spine TopologySpine LayerLeaf LayerKafka BrokersSpine 1Spine 2Leaf 1Leaf 2Leaf 3B1B2B3B4B5B6Each broker should havemultiple network paths

StrategyDescriptionUse Case
Rack-balancedEqual brokers per rackStandard HA deployment
Zone-balancedEqual brokers per availability zoneCloud deployments
Performance-tieredFaster hardware for leadersLatency-sensitive workloads
# AWS example - map AZ to rack
broker.rack=us-east-1a
# Azure example
broker.rack=eastus-zone1
# GCP example
broker.rack=us-central1-a
Replication FactorMinimum BrokersRecommended Brokers
111 (plus KRaft controllers if dedicated)
224 (2 per rack)
336 (2 per rack, 3 racks)

For complete KRaft internals including Raft consensus, failover behavior, and metadata management, see KRaft Deep Dive.

The controller quorum should be deployed across failure domains.

Controller QuorumRack 1Rack 2Rack 3Controller 1(process.roles=controller)Controller 2(process.roles=controller)Controller 3(process.roles=controller)3 controllers survive 1 failure5 controllers survive 2 failuresRaftRaftRaft
*Static quorum example:*
```properties
# Dedicated controller
process.roles=controller
node.id=1
controller.quorum.voters=1@controller1:9093,2@controller2:9093,3@controller3:9093

Dynamic quorums

Kafka 4.1+ supports dynamic controller quorums; use controller.quorum.bootstrap.servers instead of controller.quorum.voters.

DeploymentUse CaseProsCons
CombinedSmall clusters (< 10 brokers)Fewer machinesResource contention
DedicatedLarge clusters, high partition countIsolation, stabilityMore machines
# Combined controller + broker
process.roles=broker,controller
# Dedicated controller only
process.roles=controller
# Dedicated broker only
process.roles=broker

Primary DCKafka ClusterSecondary DCKafka ClusterMirrorMaker 2B1B2B3B4B5B6ProducersConsumersAsynchronous replicationRPO > 0writereadreplicate
DC 1DC 2KafkaMM2KafkaMM2DC1 AppsDC2 AppsBidirectional replicationRequires conflict handlinglocal writeslocal writesreplicatereplicate

For leader election mechanics and preferred replica election, see Replication.

Leaders should be balanced across brokers for even load distribution.

Terminal window
# Check leader distribution
kafka-topics.sh --bootstrap-server kafka:9092 --describe | \
grep "Leader:" | awk '{print $4}' | sort | uniq -c
# Trigger preferred leader election
kafka-leader-election.sh --bootstrap-server kafka:9092 \
--election-type preferred \
--all-topic-partitions

When adding or removing brokers, partitions must be reassigned.

Terminal window
# Generate reassignment plan
kafka-reassign-partitions.sh --bootstrap-server kafka:9092 \
--topics-to-move-json-file topics.json \
--broker-list "1,2,3,4,5,6" \
--generate
# Execute with throttle
kafka-reassign-partitions.sh --bootstrap-server kafka:9092 \
--reassignment-json-file reassignment.json \
--throttle 100000000 \
--execute

FactorImpact
ThroughputMore brokers = more aggregate throughput
StorageMore brokers = more total storage
Partitions~4000 partitions per broker (repository guidance)
ReplicationRF × partitions = total replicas distributed
ConsiderationGuideline
ParallelismPartitions ≥ max consumer instances
Throughput~10 MB/s per partition (repository guidance)
OverheadEach partition has memory/file handle cost
RebalanceMore partitions = longer rebalance
Partitions = max(
target_throughput / per_partition_throughput,
max_consumer_instances
)