KafkaIQ

7.1 Coordination System Operations (ZooKeeper & KRaft)

Module Overview

Goal: Explain Kafka's coordination layer once — this is the authoritative source.

What You'll Learn:

  • Why coordination exists in Kafka
  • ZooKeeper responsibilities (legacy architecture)
  • KRaft architecture (modern, ZooKeeper-free)
  • Controller quorum and Raft consensus
  • Migration from ZooKeeper to KRaft
  • Operational differences between ZK and KRaft
  • Troubleshooting coordination issues

What's NOT Covered Here:

  • Consumer group coordination (covered in Consumer modules)
  • Stream processing coordination (covered in Streams modules)
  • General distributed systems theory

Key Insight: Kafka's coordination system is being fundamentally reimagined. ZooKeeper (legacy) is being replaced by KRaft (built-in Raft consensus), eliminating external dependencies and improving scalability.


1. Why Coordination Exists

The Coordination Problem

DISTRIBUTED SYSTEM CHALLENGES:

1. Leader Election
   └─ Who is the controller?
   └─ Who is leader for partition X?

2. Cluster Membership
   └─ Which brokers are alive?
   └─ When did broker Y join/leave?

3. Metadata Management
   └─ What topics exist?
   └─ What are partition assignments?

4. Configuration Management
   └─ What are cluster configs?
   └─ What are topic configs?

5. Coordination Primitives
   └─ Distributed locks
   └─ Sequential IDs
   └─ Watches/notifications

NEED: Single source of truth for cluster state

What Coordination System Provides

CORE SERVICES:

1. Consensus
   └─ Agreement on cluster state across nodes

2. Persistence
   └─ Durable storage of metadata

3. Consistency
   └─ All nodes see same state (eventually)

4. Failure Detection
   └─ Detect when nodes fail

5. Notifications
   └─ Alert nodes when state changes

2. ZooKeeper Mode (Legacy)

ZooKeeper Overview

Apache ZooKeeper:
├─ External coordination service
├─ Runs as separate ensemble (3-5 nodes)
├─ Based on ZAB (ZooKeeper Atomic Broadcast) protocol
├─ Used by Kafka since inception
└─ Being phased out in favor of KRaft

Architecture:
┌──────────────────────────────────────┐
│  Kafka Brokers                       │
│  ├─ Broker 1                         │
│  ├─ Broker 2                         │
│  └─ Broker 3                         │
└──────────────────────────────────────┘
         ↕ (read/write metadata)
┌──────────────────────────────────────┐
│  ZooKeeper Ensemble                  │
│  ├─ ZK Node 1 (leader)               │
│  ├─ ZK Node 2 (follower)             │
│  └─ ZK Node 3 (follower)             │
└──────────────────────────────────────┘

ZooKeeper Responsibilities

WHAT ZOOKEEPER STORES FOR KAFKA:

/brokers/ids/
└─ List of live brokers (ephemeral nodes)

/brokers/topics/
└─ Topic configurations and partition assignments

/controller
└─ Current controller broker ID (ephemeral)

/controller_epoch
└─ Controller election counter

/config/
├─ Broker configs
├─ Topic configs
└─ Client configs

/admin/
└─ Administrative operations (topic creation, deletion, etc.)

/isr_change_notification/
└─ Notifications of ISR changes

/cluster/id
└─ Unique cluster identifier

ZooKeeper Operations

Starting ZooKeeper

# Start ZooKeeper (standalone)
zookeeper-server-start.sh config/zookeeper.properties

# ZooKeeper ensemble requires:
# - At least 3 nodes (recommended: 5)
# - Odd number of nodes (for quorum)
# - Fast, low-latency network between nodes

# ZooKeeper configuration (zoo.cfg):
tickTime=2000
dataDir=/var/zookeeper
clientPort=2181
initLimit=5
syncLimit=2
server.1=zk1:2888:3888
server.2=zk2:2888:3888
server.3=zk3:2888:3888

Checking ZooKeeper Health

# Check ZooKeeper status
echo ruok | nc localhost 2181
# Should return: imok

# Get ZooKeeper mode (leader/follower)
echo stat | nc localhost 2181

# Check if ZooKeeper is in quorum
echo mntr | nc localhost 2181 | grep zk_server_state

Browsing ZooKeeper Data

# Start ZooKeeper CLI
zkCli.sh -server localhost:2181

# List brokers
ls /brokers/ids
# Output: [0, 1, 2]

# Get broker info
get /brokers/ids/0

# List topics
ls /brokers/topics

# Get controller
get /controller

# Check cluster ID
get /cluster/id

ZooKeeper Operational Challenges

ISSUES WITH ZOOKEEPER:

1. External Dependency
   └─ Separate system to deploy, manage, upgrade

2. Operational Complexity
   └─ Need expertise in both Kafka and ZooKeeper

3. Scaling Limitations
   └─ ZooKeeper struggles with > 200,000 partitions
   └─ Metadata overhead grows with partition count

4. Availability Risk
   └─ ZooKeeper outage impacts Kafka control plane
   └─ Cannot create topics, elect leaders, etc.

5. Slow Metadata Operations
   └─ Controller operations limited by ZooKeeper throughput
   └─ Large clusters experience slow leader elections

6. Split-Brain Risk
   └─ Network partitions can cause consistency issues

SOLUTION: KRaft (Kafka Raft)
└─ Removes ZooKeeper dependency entirely

3. KRaft Mode (Modern Architecture)

What is KRaft?

KRaft = Kafka Raft

Key Properties:
├─ Built-in consensus protocol (Raft)
├─ No external dependencies (ZooKeeper-free)
├─ Metadata stored in internal Kafka topic
├─ Dedicated controller quorum
└─ Production-ready since Kafka 3.3

Architecture:
┌──────────────────────────────────────┐
│  Kafka Controllers (KRaft Quorum)    │
│  ├─ Controller 1 (leader)            │
│  ├─ Controller 2 (follower)          │
│  └─ Controller 3 (follower)          │
│  Stores: __cluster_metadata topic    │
└──────────────────────────────────────┘
         ↕ (metadata replication)
┌──────────────────────────────────────┐
│  Kafka Brokers                       │
│  ├─ Broker 1                         │
│  ├─ Broker 2                         │
│  └─ Broker 3                         │
└──────────────────────────────────────┘

KRaft Controller Quorum

CONTROLLER MODES:

1. Dedicated Controllers (Recommended)
   └─ Separate controller nodes (don't serve data)
   └─ Better isolation, easier to scale

2. Combined Mode
   └─ Brokers also act as controllers
   └─ Simpler deployment (fewer nodes)

QUORUM SIZE:
├─ Minimum: 3 controllers (tolerate 1 failure)
├─ Recommended: 3-5 controllers
└─ Odd number (for Raft majority)

Example:
├─ 3 controllers: Tolerate 1 failure (2 needed for quorum)
├─ 5 controllers: Tolerate 2 failures (3 needed for quorum)
└─ 7 controllers: Tolerate 3 failures (4 needed for quorum)

KRaft Configuration

Controller Configuration

# server.properties for dedicated controller

# Unique node ID (must be unique across cluster)
node.id=1

# Controller role
process.roles=controller

# Controller quorum voters (all controller nodes)
controller.quorum.voters=1@controller1:9093,2@controller2:9093,3@controller3:9093

# Listener for controller communication
listeners=CONTROLLER://controller1:9093

# Metadata log directory
metadata.log.dir=/var/kafka/metadata

# Cluster ID (generated once, shared by all nodes)
cluster.id=YourClusterIdHere

Broker Configuration (KRaft)

# server.properties for broker

# Unique node ID
node.id=101

# Broker role
process.roles=broker

# Controller quorum voters (same as controller config)
controller.quorum.voters=1@controller1:9093,2@controller2:9093,3@controller3:9093

# Broker listeners
listeners=PLAINTEXT://broker1:9092

# Data log directory
log.dirs=/var/kafka/data

# Cluster ID (same as controllers)
cluster.id=YourClusterIdHere

Combined Mode Configuration

# server.properties for combined broker+controller

node.id=1

# Combined role
process.roles=broker,controller

controller.quorum.voters=1@node1:9093,2@node2:9093,3@node3:9093

# Both broker and controller listeners
listeners=PLAINTEXT://node1:9092,CONTROLLER://node1:9093

log.dirs=/var/kafka/data
metadata.log.dir=/var/kafka/metadata

cluster.id=YourClusterIdHere

Starting KRaft Cluster

Step 1: Generate Cluster ID

# Generate unique cluster ID (once per cluster)
kafka-storage.sh random-uuid

# Output: YourClusterIdHere (use this in all configs)

Step 2: Format Storage

# Format metadata directory (on each node)
kafka-storage.sh format \
  -t YourClusterIdHere \
  -c /path/to/server.properties

# This creates metadata.properties file

Step 3: Start Controllers

# Start controller nodes
kafka-server-start.sh /path/to/controller.properties

# Repeat for all controller nodes (3-5 nodes)

Step 4: Start Brokers

# Start broker nodes
kafka-server-start.sh /path/to/broker.properties

# Brokers will connect to controller quorum

Step 5: Verify Cluster

# Check controller status
kafka-metadata.sh --bootstrap-server localhost:9092 describe --status

# List brokers
kafka-broker-api-versions.sh --bootstrap-server localhost:9092

# Create test topic
kafka-topics.sh --bootstrap-server localhost:9092 \
  --create --topic test --partitions 3 --replication-factor 3

4. ZooKeeper vs KRaft Comparison

Architectural Differences

┌───────────────────┬─────────────────────┬──────────────────────┐
│ Feature           │ ZooKeeper Mode      │ KRaft Mode           │
├───────────────────┼─────────────────────┼──────────────────────┤
│ External Deps     │ Yes (ZooKeeper)     │ No                   │
│ Metadata Storage  │ ZooKeeper znodes    │ __cluster_metadata   │
│ Consensus         │ ZAB                 │ Raft                 │
│ Controller        │ Single controller   │ Controller quorum    │
│ Failover Time     │ Seconds             │ Milliseconds         │
│ Partition Limit   │ ~200K               │ Millions             │
│ Startup Time      │ Minutes (large)     │ Seconds              │
│ Operational Comp  │ High (2 systems)    │ Lower (1 system)     │
│ Production Ready  │ Yes (mature)        │ Yes (since 3.3)      │
│ Future Support    │ Deprecated (4.0+)   │ Long-term            │
└───────────────────┴─────────────────────┴──────────────────────┘

Performance Comparison

CONTROLLER FAILOVER:

ZooKeeper Mode:
├─ Detection: 6-30 seconds (ZK session timeout)
├─ Election: 1-10 seconds
├─ Metadata reload: 1-60 seconds (depends on partition count)
└─ Total: Seconds to minutes

KRaft Mode:
├─ Detection: Immediate (Raft heartbeats)
├─ Election: Milliseconds (Raft leader election)
├─ Metadata reload: Not needed (replicated state)
└─ Total: < 1 second typically

METADATA OPERATIONS:

ZooKeeper Mode:
└─ Limited by ZooKeeper write throughput
└─ Large clusters experience slowness

KRaft Mode:
└─ Limited by Kafka throughput (much higher)
└─ Scales to millions of partitions

5. Migration from ZooKeeper to KRaft

Migration Strategies

OPTION 1: Blue-Green Migration
├─ Build new KRaft cluster
├─ Migrate applications to new cluster
├─ Decommission old ZooKeeper cluster
└─ Use case: Can tolerate downtime, simplest approach

OPTION 2: In-Place Migration (Planned)
├─ Kafka will support ZK → KRaft migration
├─ Zero-downtime migration path
├─ Planned for Kafka 3.x (check current status)
└─ Use case: Cannot tolerate downtime

CURRENT STATUS (as of Kafka 3.7):
└─ KRaft is production-ready
└─ ZooKeeper deprecated (removal in Kafka 4.0)
└─ In-place migration tool under development

RECOMMENDATION:
└─ New clusters: Use KRaft
└─ Existing clusters: Plan migration to KRaft before 4.0

Blue-Green Migration Process

STEP 1: Build KRaft Cluster

1. Deploy new Kafka cluster with KRaft
2. Configure with same capacity as old cluster
3. Create topics (match old cluster)
4. Validate cluster health

STEP 2: Migrate Producers

1. Deploy producer applications with new bootstrap servers
2. Dual-write (both clusters) temporarily
3. Validate data in new cluster
4. Stop writing to old cluster

STEP 3: Migrate Consumers

1. Deploy consumer applications with new bootstrap servers
2. Reset offsets or let consumers catch up
3. Validate consumption from new cluster
4. Stop old consumers

STEP 4: Decommission Old Cluster

1. Verify no traffic to old cluster
2. Backup data if needed
3. Stop old Kafka brokers
4. Stop ZooKeeper ensemble
5. Decommission infrastructure

DURATION: Days to weeks (depends on application count)

6. Operational Differences

Administrative Operations

CREATING TOPICS:

ZooKeeper Mode:
kafka-topics.sh --zookeeper localhost:2181 --create ...
(deprecated)

KRaft Mode:
kafka-topics.sh --bootstrap-server localhost:9092 --create ...
(same for all operations)

KEY DIFFERENCE:
└─ KRaft: All operations via bootstrap-server
└─ No need for ZooKeeper connection string

Monitoring

ZOOKEEPER MODE MONITORING:

Must monitor:
├─ Kafka brokers (JMX)
├─ ZooKeeper ensemble (JMX + mntr command)
└─ Kafka-ZooKeeper connectivity

KRAFT MODE MONITORING:

Monitor:
├─ Kafka brokers (JMX)
├─ Controller quorum (JMX)
├─ __cluster_metadata topic (replication lag)
└─ Raft metrics (leader election rate)

BENEFIT:
└─ Fewer systems to monitor

7. Troubleshooting Coordination Issues

ZooKeeper Mode Issues

Issue: ZooKeeper Unavailable

SYMPTOM:
├─ Cannot create/delete topics
├─ Controller fails to elect
└─ Brokers log ZK connection errors

INVESTIGATION:
1. Check ZooKeeper ensemble health
   └─ echo ruok | nc localhost 2181

2. Check ZooKeeper quorum
   └─ At least (n/2 + 1) nodes must be alive

3. Check network connectivity
   └─ Brokers can reach ZooKeeper?

4. Check ZooKeeper logs
   └─ Disk full? OOM? Crash?

RESOLUTION:
├─ Restart failed ZK nodes
├─ Restore ZK quorum
└─ Fix underlying issue (disk, network, etc.)

Issue: Metadata Out of Sync

SYMPTOM:
└─ Brokers have different view of cluster state

INVESTIGATION:
1. Check controller status
   └─ Is there exactly 1 controller?

2. Check ZooKeeper data
   └─ Browse /brokers/topics, /controller

3. Check broker logs
   └─ Metadata update failures?

RESOLUTION:
└─ Restart brokers (metadata resync from ZK)

KRaft Mode Issues

Issue: Controller Quorum Lost

SYMPTOM:
└─ No active controller, cannot perform admin operations

INVESTIGATION:
1. Check controller status
   kafka-metadata.sh --bootstrap-server localhost:9092 describe --status

2. Check quorum health
   └─ At least (n/2 + 1) controllers must be alive

3. Check controller logs
   └─ Raft election failures?

RESOLUTION:
├─ Restart failed controller nodes
├─ Restore controller quorum (need majority)
└─ If majority lost, may need manual recovery

Issue: Metadata Replication Lag

SYMPTOM:
└─ Slow admin operations, stale metadata on brokers

INVESTIGATION:
1. Check __cluster_metadata topic lag
   kafka-topics.sh --bootstrap-server localhost:9092 \
     --describe --topic __cluster_metadata

2. Check controller performance
   └─ CPU, disk I/O on controller nodes

3. Check Raft metrics
   └─ High commit latency?

RESOLUTION:
├─ Scale controller quorum (add nodes)
├─ Increase controller resources
└─ Check network between controllers

8. Best Practices

ZooKeeper Mode (Legacy)

✅ DO:
├─ Use 3-5 node ZooKeeper ensemble (odd number)
├─ Dedicate ZooKeeper nodes (don't co-locate with Kafka)
├─ Use fast disks for ZooKeeper (SSD)
├─ Monitor ZooKeeper health closely
├─ Keep ZooKeeper and Kafka versions compatible
└─ Plan migration to KRaft

❌ DON'T:
├─ Run single-node ZooKeeper in production
├─ Co-locate ZooKeeper with Kafka brokers
├─ Ignore ZooKeeper performance issues
└─ Exceed 200,000 partitions per cluster

KRaft Mode (Modern)

✅ DO:
├─ Use 3-5 controller nodes (odd number)
├─ Prefer dedicated controllers (not combined mode)
├─ Use fast disks for metadata.log.dir (SSD)
├─ Monitor controller quorum health
├─ Monitor __cluster_metadata replication lag
└─ Test failover scenarios

❌ DON'T:
├─ Run single controller in production
├─ Mix controller and broker roles without understanding trade-offs
├─ Ignore Raft metrics
└─ Manually modify __cluster_metadata topic

9. Key Takeaways

You've learned:

✅ Coordination provides consensus, metadata storage, and failure detection
✅ ZooKeeper is the legacy coordination system (being phased out)
✅ KRaft is the modern, built-in Raft consensus (ZooKeeper-free)
✅ Controller quorum (KRaft) provides faster failover than ZooKeeper
✅ KRaft scales better: millions of partitions vs. ~200K with ZooKeeper
✅ Migration: Blue-green or in-place (when available)
✅ Operational differences: KRaft is simpler (one system instead of two)
✅ ZooKeeper deprecated: Removal planned for Kafka 4.0
✅ Recommendation: Use KRaft for new clusters


10. Coordination System Checklist

ZOOKEEPER MODE:

☑ 3-5 ZooKeeper nodes (odd number)
☑ Fast disks (SSD) for ZooKeeper
☑ Monitor ZooKeeper health
☑ Monitor Kafka-ZK connectivity
☑ Plan migration to KRaft

KRAFT MODE:

☑ 3-5 controller nodes (odd number)
☑ Prefer dedicated controllers
☑ Fast disks for metadata.log.dir
☑ Monitor controller quorum
☑ Monitor __cluster_metadata replication
☑ Test controller failover

BOTH:

☑ Low-latency network between coordinator nodes
☑ Monitor leader election rate
☑ Document cluster ID and configuration
☑ Backup configuration files

Summary

Kafka's coordination is evolving:

ZooKeeper (Past):
├─ External dependency
├─ Operational complexity
├─ Scaling limitations
└─ Being phased out (removed in Kafka 4.0)

KRaft (Future):
├─ Built-in consensus (Raft)
├─ No external dependencies
├─ Better scalability
├─ Faster failover
├─ Simpler operations
└─ Production-ready now

Migration Path:
├─ New clusters: Use KRaft
└─ Existing clusters: Plan migration before Kafka 4.0

Remember: KRaft represents the future of Kafka. It simplifies operations, improves performance, and scales better. Start using it for new deployments today.


Congratulations!

You've completed the Kafka Operations & Administration course!

You now understand:

  • ✅ Cluster architecture and administration fundamentals
  • ✅ Broker lifecycle and topic management
  • ✅ Partitions, replication, and ISR health
  • ✅ Dynamic configuration and runtime changes
  • ✅ Comprehensive monitoring, metrics, and alerting
  • ✅ Performance tuning and capacity planning
  • ✅ Quotas and resource management
  • ✅ Coordination systems (ZooKeeper and KRaft)

Next steps:

  • Practice in non-production environments
  • Build runbooks for your specific use cases
  • Set up monitoring and alerting
  • Plan capacity for your workloads
  • Stay current with Kafka releases
  • Join the Kafka community

You're now equipped to operate production Kafka clusters with confidence!