๐Ÿ“ฆ

Download kafka-lab

54 KB โ€” Docker Compose + Kotlin Gradle project + scripts + README

โฌ‡ Download .tar.gz

Architecture

DOCKER NETWORK kafka-1 :9092 โ— Controller kafka-2 :9093 โ— Broker kafka-3 :9094 โ— Broker P0โ˜… P2 P1โ˜… P0 P2โ˜… P1 โ˜… = leader, others = replicas Schema Registry :8081 Kafka UI :8080 TOPICS orders (3 partitions, RF=3) events (6 partitions, RF=2) ยท compacted-users (compact) ยท processed-orders Kotlin Client Producer / Consumer Transactions / Multi localhost:9092-9094 Browser localhost:8080

Quick Start

# Download and extract
tar xzf kafka-lab.tar.gz && cd kafka-lab

# Start 3-broker cluster + Kafka UI
./setup.sh

# Open Kafka UI in browser
open http://localhost:8080

# Produce 100 messages
cd kotlin-client
./gradlew run --args="produce --count 100"

# Consume them
./gradlew run --args="consume --group my-group --from-beginning"

Prerequisites

  • Docker & Docker Compose โ€” for the 3-broker cluster
  • JDK 17+ โ€” for the Kotlin client
  • ~2 GB RAM free โ€” 3 Kafka brokers + Schema Registry + UI

What's Inside

kafka-lab/
โ”œโ”€โ”€ docker-compose.yml โ€” 3-broker KRaft cluster + Kafka UI + Schema Registry
โ”œโ”€โ”€ setup.sh โ€” Start cluster, create 4 topics
โ”œโ”€โ”€ teardown.sh โ€” Stop everything, remove volumes
โ”œโ”€โ”€ observe.sh โ€” CLI snapshot: topics, consumer groups, lag
โ”œโ”€โ”€ chaos.sh โ€” Kill a broker, watch failover, restart
โ”œโ”€โ”€ README.md โ€” Full guide with 7 experiments
โ””โ”€โ”€ kotlin-client/
    โ”œโ”€โ”€ build.gradle.kts
    โ””โ”€โ”€ src/main/kotlin/.../
        โ”œโ”€โ”€ ProducerExample.kt โ€” Configurable producer (acks, keys, batching)
        โ”œโ”€โ”€ ConsumerExample.kt โ€” Consumer with auto/manual commit
        โ”œโ”€โ”€ MultiConsumerDemo.kt โ€” Partition rebalancing demo
        โ”œโ”€โ”€ ExactlyOnceDemo.kt โ€” Transactional read-process-write
        โ””โ”€โ”€ Main.kt โ€” CLI entry point

Kotlin Client Commands

# Produce messages
./gradlew run --args="produce --count 100"
./gradlew run --args="produce --count 1000 --delay-ms 50 --acks all"
./gradlew run --args="produce --count 50 --key-mode random"

# Consume messages
./gradlew run --args="consume --group my-group --from-beginning"
./gradlew run --args="consume --group slow --process-time-ms 500"
./gradlew run --args="consume --group manual --auto-commit false"

# Multi-consumer (partition assignment demo)
./gradlew run --args="multi --consumers 3 --group test"

# Exactly-once semantics demo
./gradlew run --args="exactly-once"

7 Guided Experiments

1. Partition Assignment & Rebalancing

Learn: How consumer groups distribute work

Start one consumer, then add a second in the same group. Watch partitions get redistributed. Kill one โ€” watch them rebalance back. The core mechanism behind Kafka's horizontal scaling.

2. Ordering Guarantees

Learn: Why keys matter

Produce with --key-mode userid. Same userId always goes to the same partition โ†’ messages arrive in order. Switch to --key-mode random โ†’ no ordering guarantee. This is the #1 thing interviewers ask about.

3. At-Least-Once vs At-Most-Once

Learn: The fundamental delivery tradeoff

Consume with auto-commit (at-most-once) and kill mid-processing โ€” messages are lost. Switch to manual commit (at-least-once) โ€” messages get reprocessed (duplicates). Neither is "exactly-once" on its own.

4. Broker Failure & Recovery

Learn: Replication and fault tolerance

Run ./chaos.sh to kill a broker while producing with acks=all. The producer continues after a brief pause. ISR shrinks, then recovers when the broker comes back. Zero message loss.

5. Consumer Lag

Learn: Monitoring slow consumers

Produce fast, consume slow (--process-time-ms 500). Watch lag grow in Kafka UI. This is the most important operational metric โ€” if lag grows unboundedly, you need more consumers or faster processing.

6. Exactly-Once Semantics

Learn: Transactional produce-consume

The exactly-once demo reads from orders, transforms, writes to processed-orders โ€” atomically. It simulates a mid-transaction crash to show zero partial writes. Check both topics in Kafka UI.

7. Acks Modes & Throughput

Learn: Durability vs performance tradeoff

Produce 1000 messages with acks=0, acks=1, and acks=all. Compare throughput numbers. acks=0 is fastest but can lose data. acks=all waits for all replicas โ€” slowest but safest.

Pre-Created Topics

TopicPartitionsReplicationNotes
orders33Main topic for experiments
events62More partitions = more parallelism
compacted-users32Log compaction โ€” keeps latest per key
processed-orders33Output of exactly-once demo

How to Observe

Kafka UI (http://localhost:8080)

The visual dashboard โ€” open alongside your terminal:

  • Topics โ†’ orders โ†’ Partitions โ€” leader broker, replica set, ISR for each partition
  • Topics โ†’ orders โ†’ Messages โ€” browse actual messages with partition, offset, key, value
  • Consumer Groups โ€” which consumer owns which partitions, current offset vs end offset (= lag)
  • Brokers โ€” health, disk usage, partition count per broker

CLI

# Quick cluster snapshot
./observe.sh

# Watch producer output: which partition each message goes to
# Watch consumer output: partition, offset, processing time

Related