KafkaIQ

5.1 Metadata Model & Cluster State

Module Overview

Goal: Explain how Kafka represents and manages cluster state.

What You'll Learn:

  • Cluster metadata structure
  • Topic and partition metadata
  • Broker registration and discovery
  • Metadata versioning and propagation
  • Client metadata consumption
  • Metadata cache consistency

What's NOT Covered Here:

  • ZooKeeper-specific implementation (covered in Module 5.2)
  • KRaft-specific implementation (covered in Module 5.3)
  • Controller logic (covered in Module 6.1)

Key Insight: Kafka's metadata model is the source of truth for cluster topology. Understanding metadata structure explains how brokers, topics, and partitions are discovered and coordinated.


1. What is Cluster Metadata?

Definition

CLUSTER METADATA = Complete state of Kafka cluster

Includes:
├─ Broker information (id, host, port, rack)
├─ Topic configuration (partition count, RF, configs)
├─ Partition assignments (which brokers host which partitions)
├─ Leadership information (leader broker per partition)
├─ ISR membership (per partition)
├─ Controller information (which broker is controller)
└─ Configuration overrides (topic/broker-specific configs)

Purpose:
└─ Single source of truth for cluster topology
└─ Enables brokers and clients to discover and coordinate

2. Broker Metadata

Broker Registration

BROKER METADATA STRUCTURE:

Broker ID: 1
├─ Host: broker1.example.com
├─ Port: 9092
├─ Rack: us-east-1a (optional, for rack awareness)
├─ Endpoints: [PLAINTEXT://broker1:9092, SSL://broker1:9093]
├─ JMX port: 9999 (optional)
└─ Broker epoch: Used in KRaft for fencing

Broker registration:
├─ On startup: Broker registers with coordination system (ZK/KRaft)
├─ Ephemeral (ZK) or heartbeat-based (KRaft)
└─ Controller discovers new brokers

Broker Liveness

LIVENESS TRACKING:

ZooKeeper mode:
└─ Ephemeral znodes (disappear if session expires)
└─ Controller watches for broker additions/removals

KRaft mode:
└─ Brokers send periodic heartbeats to controller
└─ Controller tracks last heartbeat time
└─ Timeout → broker considered dead

Liveness states:
├─ Online: Broker responsive
├─ Offline: Broker unresponsive (failure or network issue)
└─ Fenced: Broker explicitly excluded (KRaft)

3. Topic Metadata

Topic Structure

TOPIC METADATA:

Topic: "orders"
├─ Partition count: 3
├─ Replication factor: 3
├─ Configuration:
│   ├─ retention.ms: 604800000 (7 days)
│   ├─ cleanup.policy: delete
│   ├─ compression.type: producer
│   ├─ min.insync.replicas: 2
│   └─ ... (other configs)
├─ Partitions:
│   ├─ Partition 0:
│   │   ├─ Replicas: [1, 2, 3]
│   │   ├─ Leader: 1
│   │   ├─ ISR: [1, 2]
│   │   └─ Offline replicas: [3]
│   ├─ Partition 1:
│   │   └─ ... (similar structure)
│   └─ Partition 2:
│       └─ ...
└─ Topic epoch: Incremented on metadata changes (KRaft)

Partition Assignment

PARTITION METADATA:

Partition: orders-0
├─ Topic: orders
├─ Partition ID: 0
├─ Replicas: [1, 2, 3]
│   └─ Ordered list of broker IDs hosting this partition
├─ Leader: 1
│   └─ Current leader broker
├─ ISR: [1, 2]
│   └─ In-sync replica set
├─ Leader epoch: 5
│   └─ Incremented on each leader change
├─ Offline replicas: [3]
│   └─ Replicas not currently available
└─ Adding replicas: [] (during reassignment)

4. Controller Metadata

Controller Registration

CONTROLLER IDENTIFICATION:

At any time, exactly one broker is the controller:

Controller metadata:
├─ Controller ID: Broker ID of current controller
├─ Controller epoch: Incremented on each controller election
└─ Timestamp: When controller was elected

Purpose:
├─ Manage partition leadership
├─ Handle broker failures
├─ Coordinate partition reassignments
└─ Update cluster metadata

All brokers know:
└─ Which broker is currently the controller
└─ Can route admin requests accordingly

5. Metadata Versioning

Epochs for Consistency

EPOCHS TRACK CHANGES:

Controller epoch:
└─ Incremented each time controller changes
└─ Prevents stale controllers from making decisions

Leader epoch (per partition):
└─ Incremented each time partition leader changes
└─ Enables divergence detection

Topic epoch (KRaft):
└─ Incremented on topic metadata changes
└─ Version tracking for topic configs

Broker epoch (KRaft):
└─ Incremented when broker registers
└─ Used for broker fencing (prevent zombie brokers)

Version Example

TIMELINE:

T=0:
├─ Controller: Broker 0 (epoch 1)
├─ Partition orders-0 leader: Broker 1 (epoch 0)

T=1: Controller fails, Broker 1 becomes controller
├─ Controller: Broker 1 (epoch 2)
└─ Controller epoch incremented

T=2: Partition orders-0 leader fails, Broker 2 elected
├─ Partition orders-0 leader: Broker 2 (epoch 1)
└─ Leader epoch incremented

Result:
└─ Each change tracked by epoch
└─ Stale messages rejected (lower epoch)

6. Metadata Propagation

How Metadata Spreads

METADATA DISTRIBUTION:

1. Controller makes changes:
   └─ Leader election, ISR updates, etc.

2. Controller updates metadata:
   └─ ZooKeeper (ZK mode) or Metadata Log (KRaft mode)

3. Controller sends UpdateMetadataRequest to all brokers:
   └─ Contains updated metadata for affected partitions

4. Brokers receive and apply updates:
   ├─ Update local metadata cache
   └─ Ready to serve updated metadata to clients

5. Clients fetch metadata:
   └─ MetadataRequest to any broker
   └─ Broker responds with cached metadata

UpdateMetadataRequest

UPDATE METADATA REQUEST STRUCTURE:

UpdateMetadataRequest:
├─ Controller ID: 0
├─ Controller epoch: 5
├─ Broker metadata: [(id=1, host=...), (id=2, host=...), ...]
├─ Partition states:
│   └─ For each updated partition:
│       ├─ Topic: orders
│       ├─ Partition: 0
│       ├─ Leader: 2
│       ├─ Leader epoch: 3
│       ├─ ISR: [2, 3]
│       └─ Replicas: [1, 2, 3]
└─ Live brokers: [0, 1, 2, 3]

Brokers apply updates:
└─ Merge into local metadata cache
└─ Now serve updated metadata to clients

7. Client Metadata Requests

MetadataRequest

CLIENT METADATA REQUEST:

Client sends MetadataRequest:
├─ Topics: ["orders", "users"] (or empty for all topics)
└─ Include internal topics: false

Broker responds with MetadataResponse:
├─ Brokers: [(id=1, host=broker1, port=9092), ...]
├─ Controller ID: 0
└─ Topic metadata:
    └─ For each topic:
        ├─ Topic: orders
        ├─ Error: NONE
        ├─ Partitions:
        │   └─ For each partition:
        │       ├─ Partition: 0
        │       ├─ Leader: 1
        │       ├─ Replicas: [1, 2, 3]
        │       ├─ ISR: [1, 2]
        │       └─ Offline replicas: []
        └─ Is internal: false

Client Metadata Caching

CLIENT-SIDE BEHAVIOR:

1. Initial connection:
   └─ Connect to bootstrap servers
   └─ Fetch full metadata

2. Cache metadata locally:
   ├─ Topic/partition mappings
   ├─ Leader brokers
   └─ Broker endpoints

3. Use cached metadata for routing:
   ├─ Producer: Route to partition leader
   └─ Consumer: Route to partition leader (or follower if enabled)

4. Refresh metadata on:
   ├─ Errors (NOT_LEADER_FOR_PARTITION, etc.)
   ├─ Periodic refresh (metadata.max.age.ms, default 5 min)
   └─ Topic list changes

5. Incremental updates (KIP-227):
   └─ Fetch only changed metadata (reduces overhead)

8. Metadata Consistency

Consistency Model

EVENTUAL CONSISTENCY:

Metadata updates are eventually consistent:
├─ Controller updates metadata
├─ Sends UpdateMetadataRequest to brokers
├─ Brokers apply updates asynchronously
└─ Brief window where brokers have different views

Client impact:
├─ Client metadata may be stale
├─ Clients receive errors (NOT_LEADER_FOR_PARTITION)
└─ Clients refresh and retry

Trade-off:
├─ High availability (no strong consensus per update)
└─ Occasional client retries (acceptable cost)

Handling Stale Metadata

CLIENT ERROR HANDLING:

1. Client sends request to broker based on cached metadata

2. Broker responds with error:
   └─ NOT_LEADER_FOR_PARTITION (leadership changed)
   └─ UNKNOWN_TOPIC_OR_PARTITION (topic deleted)

3. Client actions:
   ├─ Fetch fresh metadata
   ├─ Update local cache
   └─ Retry request to correct broker

4. Exponential backoff (if repeated errors)

Typical retry loop:
└─ Send → Error → Refresh → Retry → Success
└─ Usually resolves in 1-2 retries

9. Metadata Storage

Storage Location

WHERE METADATA IS STORED:

ZooKeeper mode:
└─ ZooKeeper stores authoritative metadata
└─ Controller reads/writes to ZK
└─ Brokers cache metadata locally

KRaft mode:
└─ Metadata log (Kafka topic: __cluster_metadata)
└─ Controller quorum maintains metadata log
└─ Brokers replicate metadata log

Key difference:
├─ ZK: External coordination system
└─ KRaft: Self-managed metadata (no external dependency)

10. Key Takeaways

You've learned:

✅ Cluster metadata includes brokers, topics, partitions, leadership, ISR
✅ Broker registration — brokers register on startup, tracked by controller
✅ Topic metadata — partition count, RF, configs, assignments
✅ Partition metadata — replicas, leader, ISR, leader epoch
✅ Controller metadata — which broker is controller, controller epoch
✅ Epochs track changes — controller, leader, topic, broker epochs
✅ Metadata propagation — UpdateMetadataRequest from controller to brokers
✅ Client metadata caching — fetch, cache, refresh on errors
✅ Eventual consistency — brief staleness, clients retry
✅ Storage — ZooKeeper (legacy) or metadata log (KRaft)


Summary

Kafka metadata is the cluster's single source of truth:

Metadata Components =
├─ Brokers: id, host, port, rack, liveness
├─ Topics: partition count, RF, configs
├─ Partitions: replicas, leader, ISR, epochs
├─ Controller: current controller, epoch
└─ Versioning: Epochs track changes

Propagation =
├─ Controller updates metadata
├─ UpdateMetadataRequest to brokers
├─ Brokers cache and serve to clients
└─ Eventual consistency (brief staleness)

Client Interaction =
├─ MetadataRequest to any broker
├─ Cache metadata locally
├─ Refresh on errors or periodic timeout
└─ Retry with fresh metadata

Storage =
├─ ZooKeeper (legacy, external system)
└─ KRaft (modern, self-managed metadata log)

Remember: Metadata is the nervous system of Kafka. Understanding how metadata is structured, propagated, and cached explains how the cluster coordinates and how clients discover brokers and partitions.

Next up: Module 5.2 — ZooKeeper Coordination (Legacy) — Historical coordination system.