An introduction to Apache Kafka & Amazon MSK (Managed Kafka Service)

By | February 5, 2024

A Quick Summary of Kafka (The TLDR)

For those who want to avoid committing to a long read, here is a summary of the article below. Hopefully, it whets your appetite, and you will want to read more.

  1. Apache Kafka’s Core Functionality: It’s a powerful distributed streaming platform capable of handling high volumes of data. It operates on a publish-subscribe messaging model, efficiently managing real-time data streaming and processing.
  2. Data Handling and Storage: Kafka stores data in a structured, immutable log, allowing for reliable, sequential data processing and easy historical data access. This design supports both real-time and historical data analysis.
  3. Scalability and Reliability: Kafka’s distributed architecture ensures scalability and fault tolerance. Topics can be partitioned and distributed across multiple servers, allowing for high throughput and redundancy.
  4. Consumer Flexibility: Kafka supports multiple independent consumers and consumer groups, enabling parallel data processing and efficient message distribution without losing message integrity or order.
  5. Real-Time Processing: Beyond messaging, Kafka excels in real-time data processing, offering capabilities for stream processing, time-windowed operations, and interactive queries through Kafka Streams.
  6. Amazon Managed Streaming for Kafka (MSK): Amazon MSK simplifies the deployment and management of Kafka, providing a managed service that integrates with AWS for scalability, security, and maintenance.
  7. Best Practices and Insights: Effective Kafka and Amazon MSK usage involves optimal partitioning, proactive lag management, leveraging cloud-native features, efficient cluster management, simplifying application complexity, seamless system integration and message schema validation. Combining Kafka with other AWS services like SQS and SNS can optimise specific tasks.
  8. Strategic Use Cases: Kafka is ideal for complex, high-volume data streaming needs, whereas integrating it with more straightforward AWS services or choosing Amazon Kinesis might be better for more specific use cases or smaller-scale projects.

In essence, Kafka and Amazon MSK offer a robust framework for building sophisticated, event-driven applications and services capable of processing vast amounts of data in real-time, with the flexibility to scale and adapt to various business needs.

Now read on!!

The Fundamentals of Kafka

Kafka introduces a transformative approach to messaging by enabling applications to publish (write) and consume (read) messages within a structured, immutable, and ordered log of events. This design is central to Kafka’s efficiency and reliability in data processing across distributed systems.

Distributed Architecture:

Kafka operates on a cluster of servers, each serving as a broker that manages data storage and processing. Kafka’s topics are distributed across these brokers by partition, and each partition is copied across multiple brokers, enhancing scalability and fault tolerance.
This distributed nature allows Kafka to handle massive amounts of data from numerous sources without sacrificing performance or integrity.


Topics are designated channels or categories for publishing messages relevant to particular business functions or data streams.


Topics in Kafka are split into partitions across servers for scalability (load balancing), reliability and parallel processing. Each partition is a commit log, a stream of immutable ordered events/messages. When published to a topic, events are appended to the end of a log and assigned a sequential ID called an offset. Producers can specify a partition key to determine the target partition within the topic.

High availability and Fault tolerance:

Each partition is replicated across a predetermined number of servers.
Within this architecture, one server is designated as the “leader” for each partition, responsible for processing all read and write operations, while the remaining servers, known as “followers,” synchronise with the leader to maintain up-to-date replicas.

Leadership is dynamically managed; in the event of a leader’s failure, a follower is automatically promoted to the new leader. This ensures continuous availability and load balancing, as servers alternate roles between leaders for some partitions and followers for others, optimising resource utilisation and system resilience.

Data Retention:

Regardless of consumption status, every published message is preserved for a predefined retention period. This duration is adjustable; for example, setting the log retention policy to 48 hours ensures message availability for consumption within this timeframe before automatic deletion occurs to reclaim storage. And the limit of retention is the limit of your budget.

Kafka’s architecture ensures that its performance metrics remain stable, regardless of the volume of retained data, facilitating extensive data storage without impacting system efficiency.

Publisher (Producer) Interaction with Kafka:

Message Publication:

  • Topic-Based Publishing: Producers publish messages to specific topics. Each topic is a commit log, a stream of immutable ordered events/messages. When events are published to a topic, they are appended to the end of a log. Each topic is partitioned, spreading the data across multiple servers for load balancing.

Efficiency and Reliability:

  • Batching: Producers can send messages in batches to improve throughput and reduce network overhead.
  • Asynchronous Sending: Kafka allows producers to send messages asynchronously. While asynchronous sending can improve performance and resource utilisation. However, remember that data can be lost when asynchronous sending is used.
  • Configurable Consistency: Producers can choose the consistency level (e.g., wait for acknowledgement from the leader or all replicas), balancing between performance and data durability.

Security and Control:

  • Authentication and Authorisation: Producers can be authenticated, and their permissions to publish to specific topics can be controlled.
  • Data Encryption: Supports data encryption in transit, ensuring that the data published to topics is secure and protected from unauthorised access.

Consumer (Subscriber) Interaction with Kafka:

Message Consumption:

Consumer Groups and Scalability:

  • Consumer Groups: Consumers, when subscribing to a Kafka topic, provide a consumer group identifier, which Kafka uses to keep track of the consumer’s offset. When multiple consumers are organised into a consumer group, Kafka ensures that each partition is only consumed by one consumer from the group. This Mechanism allows for the dataset to be processed in parallel, significantly speeding up processing time and ensuring that the workload is evenly distributed among the consumers.
  • Offset Management: Kafka tracks the offset (position) of each consumer in each partition, allowing consumers to pause and resume message consumption without losing their place.

Reliability and Performance:

  • At-least-once Delivery: Kafka ensures that messages are delivered at least once but may deliver messages more than once in specific failure scenarios.
  • Commit Mechanism: Consumers can commit their offsets to Kafka. If a consumer fails, it can resume consuming from the last committed offset, ensuring no data loss.
  • Fault Tolerance: If a consumer fails, Kafka rebalances the partitions among the remaining consumers in the group, ensuring that data processing continues without interruption.

Flexibility and Extensibility:

  • Stream Processing: Kafka provides capabilities for stream processing, allowing consumers to process, transform, and enrich data as it arrives.
  • Integration with External Systems: Consumers can easily integrate with external systems for further data processing, storage, or analytics.

How Kafka Enables Decoupling and System Collaboration

Kafka’s messaging framework fosters a loosely coupled architecture, allowing system components to interact with minimal dependencies on each other. This loose coupling is pivotal for constructing resilient and scalable systems.

  • Decoupling of Producers and Consumers: By mediating communication through topics, Kafka allows producers and consumers to remain oblivious to each other’s existence. Such an arrangement permits independent updates and maintenance of system components, thereby enhancing overall system robustness and adaptability.
  • Event-Driven Choreography: Kafka promotes a model of interaction where applications autonomously react to events (messages) they are interested in. This self-directed reaction to events is referred to as choreography, contrasting with orchestrated systems where a central authority dictates interaction. Choreography leads to more flexible systems that are easier to evolve.

Real-World Example: E-Commerce Platform

Consider an e-commerce platform where various services (applications) collaborate to provide a seamless shopping experience. When a customer places an order, the order service publishes a message to a Kafka topic. This message might contain order details such as purchased items, customer information, and payment status.

  • Order Processing: A payment service consumes messages from the order topic to process payments. Upon successful payment, it publishes a payment successful event to another topic, which might trigger the shipping service to start the delivery process.
  • Inventory Management: Simultaneously, an inventory service consumes the original order message to update stock levels. If the stock is low, it might publish a low stock level event to a topic, which triggers a procurement service to reorder stock.

This decentralised, event-driven approach enables each service to operate independently, reacting to relevant events without needing direct commands from a central system. The result is a highly resilient and scalable system that can adapt to changing demands and easily integrate new services.

Real-Time Stream Processing

Kafka’s capabilities extend beyond messaging and into the realm of real-time stream processing. Kafka Streams, a client library for building applications and microservices, where the input and output data are stored in Kafka clusters, enables developers to build complex processing logic on Kafka data quickly.

  • Stream Processing Features: Kafka Streams supports a wide range of stream processing operations, including stateless transformations (such as map and filter), stateful transformations (such as aggregation and windowing), and joins between streams and tables. This flexibility allows developers to implement complex data processing and analytics applications directly on the Kafka cluster.
  • Time-Windowed Operations: Time-windowed operations are crucial for real-time analytics. Kafka Streams enables data processing in time-based windows, allowing for the computation of results over specific periods. This is particularly useful for applications that require rolling aggregates or analysis over sliding time intervals.
  • Interactive Queries: Kafka Streams supports interactive queries, enabling applications to query the state stored in Kafka in real-time. This feature allows for the creation of dynamic dashboards and real-time analytics applications that can provide insights into the streaming data as it flows through the Kafka cluster.

Extending Kafka with Amazon MSK

Amazon Managed Streaming for Kafka (MSK) enhances Kafka’s capabilities by offering a fully managed service that simplifies cluster management and integrates seamlessly with other AWS services. It provides high availability, security features, and the convenience of automatic scaling and maintenance, allowing businesses to focus more on application development and less on infrastructure management.

In summary, Kafka revolutionises messaging and data processing with its robust, scalable architecture. Its approach to event logging and the ability to efficiently publish and consume messages make it an invaluable tool for developing complex, event-driven applications.

Advice and Best Practices

Through my extensive experience with Apache Kafka and Amazon Managed Streaming for Apache Kafka (MSK), I’ve identified key strategies and insights that can help harness their full potential for handling multiple consumers and enabling real-time stream processing. Below, I distil these learnings into actionable best practices.

Optimal Topic Partitioning for Enhanced Performance

  • Assessment and Planning: Begin with evaluating your expected data volume and consumer throughput to decide the correct number of partitions per topic. While more partitions can increase parallelism, they add to cluster management overhead.
  • Dynamic Adjustment: Keep your system agile by using tools to adjust partitions as data volumes or consumer patterns evolve, maintaining a balanced and efficient Kafka setup.

Proactive Consumer Lag Management

  • Real-time Monitoring Tools: Leverage Kafka’s JMX metrics and external tools such as Prometheus and Grafana to keep an eye on consumer lag and throughput.
  • Proactive Management: Implement alert systems for excessive consumer lag to swiftly address performance dips or bottlenecks.

Exploiting Amazon MSK’s Cloud-Native Features

  • Auto-Scaling: Use Amazon MSK’s auto-scaling to adjust cluster sizes dynamically, balancing performance needs with cost efficiency.
  • Security Practices: Secure your Kafka clusters with AWS best practices, including IAM roles, TLS encryption in transit, and data encryption at rest.

Efficient Kafka Cluster Management

  • Performance Optimisation: Regularly tweak Kafka cluster and broker settings for peak performance, considering AWS-managed services for operational ease.
  • Resource Utilisation: Employ tools like AWS CloudWatch to monitor resources, ensuring brokers are optimally provisioned.

Simplifying Application Complexity

  • Adopt Architectural Best Practices: Design for fault tolerance, error handling, idempotency, and exactly-once processing, utilising Kafka Streams and transactional APIs for complex operations.
  • Integration Flexibility: My experience taught me the importance of mixing Kafka with services like Amazon SQS, SNS, and AWS Step Functions for more straightforward, context-specific tasks, balancing complexity and efficiency.

Seamless System Integration

  • Adopting Integration Patterns: Leverage patterns such as event sourcing and CQRS for effective Kafka or MSK integration with your system architecture.
  • API Management: Manage external access to Kafka data securely and efficiently with API gateways or service meshes.

Preventing System Failures in Kafka with a Schema Registry

If messages in Apache Kafka are not validated against a schema, several issues can arise, leading to data inconsistency, application errors, or system failures. Without validation, there’s a risk of publishing malformed data, incompatible data formats, or incorrect data structures, which can disrupt data processing pipelines and compromise data integrity. Consumers might receive data they cannot process, causing failures or inaccuracies in data-driven applications and analytics.

To address these challenges and ensure data quality and compatibility, the integration of a Schema Registry with Kafka becomes essential. A Schema Registry is an external component that manages schemas for Kafka topics, providing a centralised repository for storing and retrieving message schemas.

Here’s how the Schema Registry works to prevent the aforementioned issues:

  • Producers use the Schema Registry to validate messages against the predefined schemas before publishing. This step ensures that only correctly formatted data enters the Kafka system, reducing the risk of data issues downstream.
  • Consumers, on the other hand, can consult the Schema Registry when retrieving messages to verify that the data matches the expected schema. This validation step helps consumers process data reliably, maintaining system stability and data accuracy.
  • The Schema Registry also facilitates schema evolution, allowing schemas to be updated in a controlled manner without breaking existing applications. It ensures that new and old schema versions are compatible, preventing potential disruptions as data structures evolve over time.

In summary, by implementing a Schema Registry, organisations can enforce strict data validation rules for messages entering and exiting Kafka, mitigating risks associated with unvalidated data and ensuring a robust, reliable data infrastructure.

Watch the video regarding Schemas here

Practical Insights From My Real-World Use

Kafka’s robust capabilities shine in facilitating complex data workflows and inter-system collaborations, especially with its support for CDC and event sourcing. Its scalability and reliability are particularly effective for large-scale, intricate streaming needs.

On the flip side, for smaller tasks or when operating within tightly defined service contexts, integrating Kafka with simpler AWS services—such as SQS for straightforward messaging or Step Functions for explicit orchestration—can streamline operations without the overhead of Kafka’s event-driven complexities.

Comparing Kafka with Amazon Kinesis, I’ve found Kinesis to be more cost-effective and more straightforward for specific use cases, like immutable message streams within a bounded context, thanks to its clear limitations on consumer count and data retention.

For broader, inter-system communication, Kafka’s no-limit retention period and capacity for numerous consumers make it my go-to for durable, scalable, and accessible event streams.

This strategic approach—leveraging Kafka for its high-capacity, complex event streaming capabilities while employing more specialised AWS services for targeted tasks—facilitates a balanced, efficient architectural design, ensuring optimal performance across diverse business activities.

Leave a Reply