Spark-Streaming Kafka Direct Streaming API & Parallelism
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Apache Kafka is a distributed publish-subscribe messaging system that is often used to process streaming data. Spark Streaming is an extension of the core Spark API that enables scalable, high-throughput, fault-tolerant stream processing of live data streams. The integration of Spark Streaming and Kafka has become increasingly popular for processing real-time data streams because it combines the simplicity and scalability of Kafka with the power and flexibility of Spark. One of the most potent ways to integrate these technologies is through the Kafka Direct Stream API, introduced in Spark 1.3.
Apache Kafka Direct Stream API in Spark Streaming
The Kafka Direct Stream API (also known as Direct Kafka API or Direct Approach) in Spark Streaming is a more efficient method of consuming data from Kafka compared to the earlier Receiver-based approach. In the Receiver-based approach, data is received through Kafka's high-level API and then stored in Spark executors, potentially causing data duplications in memory and requiring additional overhead to track offsets.
In contrast, the Direct Stream API uses a simpler, more efficient approach where offsets are managed directly and data is not replicated unnecessarily. This API directly queries Kafka to retrieve only the offsets and data that are relevant, thus reducing memory usage and improving performance.
Technical Overview of Kafka Direct Stream API Implementation
When using the Direct Stream API, Spark periodically queries Kafka to find the latest offsets in each topic and partition and then computes the offsets to process by comparing them with the offsets of the processed data. This results in a set of ranges (offset ranges) for each partition. Spark assignments these offset ranges across a cluster to process the data parallel. After processing these ranges, Spark updates the offsets in Kafka, ensuring exactly-once processing semantics through idempotent updates.
Here's a basic example in Scala to demonstrate using the Direct Stream API:
Parallelism in Kafka Direct Streaming
Parallelism in Kafka Direct Streaming is primarily determined by the number of partitions in the Kafka topic itself. Each partition is read in parallel by a separate task in Spark, so having multiple partitions increases the parallelism available to your Spark job.
Furthermore, developers can control the level of parallelism using partitioning strategies when defining the Kafka stream. For instance, the LocationStrategies.PreferConsistent approach distributes the partitions uniformly across the available executors.
Here's a table summarizing the key considerations for achieving high parallelism in Kafka Direct Streaming:
| Factor | Description |
| Number of Kafka Partitions | More partitions allow more parallel reads. |
| Number of Spark Executors | More executors allow more tasks to be processed simultaneously. Ideally, this should match or exceed the number of Kafka partitions. |
| Location Strategy | Strategies like PreferConsistent help distribute the workload evenly across all available executors. |
Enhancements with Spark Structured Streaming
As of Spark 2.x, Structured Streaming provides a higher-level API that integrates better with Spark SQL and DataFrames. It simplifies stream processing even more by allowing you to write streaming queries similar to batch processing queries.
For those who require combining the benefits of Kafka and Structured Streaming, significant enhancements include robust handling of offsets and improved event-time processing capabilities.
In conclusion, the Direct Streaming API for Kafka provides a powerful mechanism for streaming processing by leveraging Spark's advanced processing capabilities with Kafka's high-throughput ingestion capabilities. It promises scalability, fault tolerance, and significant performance benefits tailored for today's high-volume data processing environments.
Related reading
- Spark - Get earliest and latest offset of Kafka without opening stream
- Spark 2.3.0 Failed to find data source kafka
- Spark 3.x Integration with Kafka in Python
- Spark + Kafka integration - mapping of Kafka partitions to RDD partitions
- Spark 2.3 submit on Kubernetes error
- Spark batch reading from Kafka & using Kafka to keep track of offsets
- spark streaming + kafka - spark session API
- Spark Streaming + kafka INFO SimpleConsumer Reconnect due to socket error java.nio.channels.ClosedChannelException

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.