Apache Kafka — Concepts I Learned

Practice repo: github.com/Qleoz12/curso-apache-kafka-master — clone it, run the eight cases, and map each concept below to real code.

I first heard about Apache Kafka around 2019. I understood the basics (broker, topic, producer, consumer), but I had not sat down to practice it end-to-end in a while. RabbitMQ was already familiar — queues, exchanges, routing — and Kafka feels related: both are about moving messages between services without tight coupling. In real backends you constantly touch APIs, microservices, and queues; Kafka keeps showing up in job posts and system diagrams, so skipping hands-on practice did not make sense.

I retook it with a local Spring Boot lab (str-producer on 8097, str-consumer on 8197, Kafka on 9092, Kafdrop on 19000). This page is my cheat sheet while running that repo. For curls and every endpoint, see Try It Yourself; for the full case index, see the Learning hub.

References (credit where I refreshed ideas)

These videos helped me reconnect theory with practice — especially the Spring Kafka course:

Video Channel
#1 Qué es Apache Kafka — Curso Spring Kafka de Cero a Experto DavinchiCoder
Domina Apache Kafka y multiplica tus oportunidades laborales La Tecnología Avanza
Kafka en 10 minutos — Conceptos esenciales y arquitectura pirobits

The lab code is mine; the explanations below lean on those creators for structure and motivation.


1. Core architecture

Producer → Broker → Topic → Partitions → Consumer — the minimum mental model before touching Spring code.

Kafka core architecture: producer, broker, topic, partitions, and consumer

Figure 1 — Basic data flow from publish to consume.

Broker

Definition: A Kafka server that stores topics, serves producers and consumers, and coordinates partitions.

Why it matters: Brokers are the runtime of Kafka; clustering them gives fault tolerance and scale.

In my project: Kafka listens on 9092; Kafdrop (19000) connects to the same cluster for inspection.

Example: localhost:9092 in Spring application.yml bootstrap servers.

Interview version: A Kafka broker is a node that persists topic partitions and handles produce/fetch requests. A production cluster runs multiple brokers for replication and availability.

Topic

Definition: A named, append-only log category where producers publish and consumers subscribe.

Why it matters: Topics decouple producers from consumers and let many services share the same event stream.

In my project: Each lab case uses its own topic (basic message, keyed messages, JSON events, retry/DLT, request-reply, filter, inventory).

Example: Producer REST receives HTTP, then publishes to the configured topic via KafkaTemplate.

Interview version: A topic is a logical channel of records. Producers write to topics; consumers read from them without knowing who produced the data.

Partition

Definition: A topic is split into ordered partitions; each partition is an ordered, immutable sequence of records.

Why it matters: Partitions enable parallelism: multiple consumers in a group can read different partitions at once.

In my project: Lab 02 demonstrates message keys and ordering within a partition.

Example: Three keys → three partition streams; same key → same partition → order preserved per key.

Interview version: Partitions are Kafka’s unit of parallelism. Ordering is guaranteed per partition, not globally across a topic.

Producer

Definition: A client that sends records to Kafka topics.

Why it matters: Producers are the entry point for event-driven systems.

In my project: str-producer (Spring Boot, port 8097) exposes REST; HTTP requests become Kafka records.

Example: POST to producer REST → message published to topic.

Interview version: A producer serializes records and sends them to a topic partition, optionally using a key for routing.

Consumer

Definition: A client that reads records from Kafka topics.

Why it matters: Consumers implement business logic reacting to events asynchronously.

In my project: str-consumer (port 8197) uses @KafkaListener to process messages from topics.

Example: Listener method receives ConsumerRecord and applies domain logic (log, transform, persist).

Interview version: A consumer subscribes to topics, fetches records, processes them, and commits offsets.


2. Position and order: Offset + Message Key

Offsets mark where you are in a partition; keys decide which partition a message lands in.

Kafka offset and message key: position within a partition and routing by key

Figure 2 — Same key always maps to the same partition; there is no global order across partitions.

Offset

Definition: A monotonically increasing ID of a record within a partition.

Why it matters: Consumers track offsets to know what they have processed and to replay if needed.

In my project: Visible in Kafdrop and consumer logs when processing lab messages.

Example: After consuming partition 0 up to offset 42, the consumer commits offset 43 as the next read position.

Interview version: An offset is the position of a message in a partition. Consumer groups commit offsets to resume after restarts without reprocessing everything.

Message Key

Definition: Optional bytes sent with a record used to choose the target partition.

Why it matters: Keys colocate related events for ordered processing per entity.

In my project: Lab 02 — same key → same partition → order per key.

Example: Key order-123 always lands in the same partition.

Interview version: Message keys route related events to the same partition so ordering holds for that key.


3. Scalable consumption: Consumer Group

Consumer groups are how Kafka scales reads without processing the same partition twice in one group.

Kafka consumer group: partition assignment and horizontal scaling

Figure 3 — Each partition goes to at most one consumer in the group; parallelism is capped by partition count.

Consumer Group

Definition: A set of consumers that cooperate to consume a topic; each partition is assigned to at most one consumer in the group.

Why it matters: Groups scale consumption horizontally without duplicate processing per partition.

In my project: Consumer group-id in Spring config defines which group processes lab topics.

Example: Two instances with the same group-id split partitions; two different groups each get a full copy of the stream.

Interview version: Consumer groups enable scalable consumption. Kafka assigns each partition to one consumer in the group at a time.

Horizontal scaling

Definition: Adding more instances instead of bigger machines.

Why it matters: Kafka scales reads via partitions + consumer groups; writes via more partitions and brokers.

In my project: Run multiple consumer instances with the same group-id to parallelize partition processing.

Example: 6 partitions, 3 consumers → ~2 partitions each.

Interview version: Horizontal scaling in Kafka means more partitions and more consumers in a group, bounded by partition count.


4. Serialization and deserialization

Kafka stores bytes, not Java objects. Producer and consumer must agree on the format.

Kafka serialization flow: Java object to bytes via JsonSerializer and back via JsonDeserializer

Figure 4 — Producer serializes before send; consumer deserializes on read (lab 03 uses JSON).

Serialization

Definition: Converting an object or payload into bytes for Kafka.

Why it matters: Kafka only stores bytes; serializers define the on-wire format.

In my project: String serializer for simple labs; JSON serializer for event payloads (lab 03).

Example: JsonSerializer on KafkaTemplate for typed events.

Interview version: Serialization turns application objects into bytes. Producer and consumer must agree on format and schema.

Deserialization

Definition: Converting Kafka bytes back into application objects.

Why it matters: Consumers need compatible deserializers with producers.

In my project: @KafkaListener methods deserialize JSON events in lab 03.

Example: JsonDeserializer configured with trusted packages for Spring Kafka.

Interview version: Deserialization is the inverse of serialization at the consumer. Mismatched serializers cause poison messages or failures.


5. In my Spring Boot lab

This is how the concepts above map to runnable services in curso-apache-kafka-master.

Spring Boot Kafka lab: HTTP ingress, str-producer, Kafka cluster, str-consumer, and Kafdrop

Figure 5 — HTTP on 8097 publishes; 8197 consumes; Kafdrop on 19000 inspects topics.

Golden rule: to publish a lab message, always call str-producer (8097). The consumer is for processing and Case 07 GET queries — not for sending messages.

See also Lab architecture for Mermaid diagrams and Case 08 (Kafka Streams).

KafkaTemplate

Definition: Spring abstraction for sending messages to Kafka.

Why it matters: Simplifies sync/async sends, headers, and topic selection.

In my project: Primary send path in str-producer; also used in str-consumer for retry, DLT, and reply (infrastructure, not main business ingress).

Example: kafkaTemplate.send(topic, key, payload).

Interview version: KafkaTemplate is Spring’s producer API. Having it in a consumer service usually means retry, DLT, or reply — not that the service is the main HTTP producer.

@KafkaListener

Definition: Spring annotation declaring a method as a Kafka message handler.

Why it matters: Declarative consumption with container-managed threading and acks.

In my project: Core pattern in str-consumer for all seven Spring consumer cases.

Example:

@KafkaListener(topics = "my-topic", groupId = "my-group")
public void listen(String message) { ... }

Interview version: @KafkaListener registers a consumer method. Spring Kafka manages polling, deserialization, and error handling hooks.


6. Resilience and integration patterns

These patterns show up in Cases 04–06 of the lab.

Retry Topic

Definition: A secondary topic where failed messages are republished for delayed reprocessing.

Why it matters: Retries transient failures without blocking the main consumer thread indefinitely.

In my project: Lab 04 — retry flow before sending to DLT.

Example: Processing fails → message routed to retry topic → consumer retries with backoff.

Interview version: Retry topics decouple immediate failure from re-attempts, often with backoff, instead of infinite in-process retries.

Dead Letter Topic (DLT)

Definition: A topic that stores messages that failed after retries, for manual inspection or alternate handling.

Why it matters: Prevents poison messages from blocking the pipeline forever.

In my project: Lab 04 — final destination when retries are exhausted.

Example: @DltHandler or Spring Kafka non-blocking retry sends to *.DLT topic.

Interview version: A DLT quarantines messages that cannot be processed. Operators fix data or replay after correcting the bug.

Request-Reply

Definition: A pattern where a consumer sends a reply record correlated to the original request, often via a reply topic.

Why it matters: Enables RPC-style workflows over Kafka while keeping async transport.

In my project: Lab 05 — correlation between request and response topics.

Example: Request carries correlationId header; reply producer uses the same id.

Interview version: Request-reply over Kafka uses correlation IDs and reply topics. It simulates RPC but remains event-driven at the broker level.

Correlation ID

Definition: An identifier linking a request message to its reply.

Why it matters: Essential when many in-flight request-reply pairs share topics.

In my project: Lab 05 request-reply flow.

Example: Header kafka_correlationId matches pending client callback.

Interview version: Correlation IDs let clients match asynchronous replies to the original request in request-reply patterns.

RecordInterceptor

Definition: Hook that inspects or modifies records (or headers) before listener invocation.

Why it matters: Cross-cutting concerns: filtering, MDC logging, metrics, dropping bad records.

In my project: Lab 06 — text filter / interceptor behavior.

Example: Interceptor drops or flags messages that fail a text rule before @KafkaListener runs.

Interview version: Record interceptors implement cross-cutting consumer logic without polluting every listener method.


7. Why Kafka in system design

Event-driven architecture

Definition: Services communicate by producing and consuming events instead of synchronous direct calls.

Why it matters: Loose coupling, independent scaling, and temporal decoupling.

In my project: HTTP → producer → Kafka → consumer replaces a single monolithic request chain.

Example: Inventory update event consumed asynchronously (lab 07).

Interview version: Event-driven architecture uses a broker so producers and consumers evolve independently and scale on different axes.

Decoupling

Definition: Reducing direct dependencies between services so changes on one side do not ripple immediately to the other.

Why it matters: Kafka buffers and persists; consumers can be down without losing events (within retention).

In my project: Producer does not call consumer HTTP; only Kafka sits between them.

Example: Spike in HTTP traffic is absorbed by the broker while consumers catch up.

Interview version: Kafka decouples producers and consumers in time and space — they only share topic contracts, not deployment or availability.


Quick recap (all concepts)

Kafka concepts cheat sheet: broker, topic, partition, offset, producer, consumer, group, key, serialization

Figure 6 — One-page summary. Producer serializes before send; consumer deserializes on read.


Lab index (my eight cases)

# Topic
01 Basic Kafka message
02 Message key and partition ordering
03 JSON events
04 Retry + Dead Letter Topic
05 Request-reply
06 Text filter / interceptor
07 Kafka → inventory / DB persistence
08 Kafka Streams (Pipe, LineSplit, WordCount)

See Lab architecture for diagrams and ports.

Kafka Streams concepts (Case 08)

Concept Where
KStream str-streamsbuilder.stream()
KTable WordCount — .count()
Topology topology.describe() on startup
State Store counts-store in WordCount
APPLICATION_ID streams-pipe, streams-linesplit, streams-wordcount

Full walkthrough: Kafka Streams — Pipe, LineSplit, WordCount.