Lab 01 — Mini Broker (a faithful partitioned-log)
Phase: 02 — Event Ingestion & Messaging | Difficulty: ⭐⭐⭐⭐☆ | Time: 6–8 hours
You don't understand Kafka until you've built one. This lab implements the Kafka mental model in ~200 lines of pure Python: a partitioned, offset-addressed log with keyed partitioning, absolute monotonic offsets that survive retention, consumer-group offset tracking + replay, partition assignment + rebalancing, log compaction (the changelog→table duality), consumer lag, and a dead-letter-queue path that quarantines poison messages without blocking the pipeline.
What you build
partition_for_key— stable hashing → per-key ordering (P01 carried forward)Partition— append-only log with absolute offsets;retain_count/retain_timeadvancestart_offset(records age out) but offsets never renumbercompacted_view— fold a keyed log into the latest-value-per-key table; tombstones (valueNone) delete — the basis of KTables and CDC snapshotsassign_partitions—rangeandroundrobinassignors; re-running with a different membership is a rebalanceConsumerGroup— committed offsets,poll,commit_through,seek(replay),lagingest— validate-at-ingress; valid → main log, invalid → DLQ with the reason attached so the pipeline keeps flowing
Key concepts
| Concept | What to understand |
|---|---|
| Per-key ordering | the only ordering that exists at scale; chosen by the partition key |
| Absolute offsets | retention deletes data but offsets stay stable (log_start_offset) |
| Consumer lag | Σ(end − position) — the #1 streaming SLI |
| Replay = seek | rewind offsets; the platform's most valuable capability |
| Compaction | a keyed log is a table; tombstones delete |
| DLQ | poison messages quarantined with a reason; the pipeline never blocks |
Run
pip install -r requirements.txt
pytest test_lab.py -v
LAB_MODULE=solution pytest test_lab.py -v
Success criteria
- All 15 tests pass.
- You can explain why
test_retention_by_count_advances_start_offsetassertsend_offset == 10even after dropping 6 records (offsets never renumber). - You can explain why
seek(0, 0)makes lag jump back up — and why that's a feature. - You can state what the consumer of a compacted topic gets vs a regular topic.
Extensions
- Add replication: each partition has RF replicas + an ISR;
produce(acks="all")only returns oncemin.insync.replicashave it; kill a replica and watch the ISR shrink (P01 quorum math made concrete). - Add idempotent producer semantics (producer id + sequence number) so a retried
producedoesn't duplicate (P01 exactly-once carried forward). - Add a DLQ replay/redrive: after fixing the validator, re-ingest the DLQ into main and assert the poison records now land.
- Add sticky assignment and measure how many partitions move on rebalance vs range
(the Kafka
CooperativeStickyAssignormotivation).