Big Data 19 min read

Understanding Apache Storm Architecture, Stream Groupings, and the Acker Mechanism

This article provides a comprehensive overview of Apache Storm’s architecture, including the roles of Nimbus, Supervisor, and ZooKeeper, explains various stream groupings, details the Acker mechanism, and describes task execution, parallelism calculation, and internal data flow within the Storm cluster.

Architect
Architect
Architect
Understanding Apache Storm Architecture, Stream Groupings, and the Acker Mechanism

This article is a personal summary of learning and using Apache Storm, compiled from the official website, many community articles, the book "Storm Applied: Strategies for Real‑Time Event Processing", and the author’s own experience.

Storm Cluster Architecture

Storm uses a master‑slave architecture. The master node, Nimbus, distributes user code to workers, while the slave nodes, Supervisors, manage worker processes. Coordination information is stored in a ZooKeeper ensemble.

Nimbus : the master node that assigns topologies (spouts/bolts) to specific workers.

Supervisor : a slave node that launches and terminates worker processes. The number of slots per supervisor is configured via supervisor.slots.ports , each slot mapping to a worker process.

ZooKeeper : coordinates Nimbus and Supervisors; if a supervisor fails, Nimbus re‑assigns the topology to other supervisors.

Stream Groupings

Stream grouping determines how tuples are routed from a spout/bolt to downstream tasks.

Shuffle Grouping : randomly distributes tuples across tasks, ensuring each task receives roughly the same number of tuples without duplication.

Fields Grouping : routes tuples with the same field value to the same task.

Partial Key Grouping : similar to fields grouping but uses a subset of the field, improving load balance for skewed data.

All Grouping : every task receives a copy of each tuple.

Global Grouping : all tuples are sent to the task with the smallest ID.

None Grouping : equivalent to shuffle grouping.

Direct Grouping : the emitting task explicitly selects the target task.

Local or Shuffle Grouping : if the target bolt has tasks on the same worker JVM, tuples are sent locally; otherwise they are shuffled.

Custom groupings can be implemented by providing a class that implements backtype.storm.grouping.CustomStreamGrouping with the method List<Integer> chooseTasks(int taskId, List<Object> values) .

Acker Mechanism

The Acker bolt tracks the processing of tuple trees. When a spout creates a tuple, it registers the tuple with the Acker. Each bolt, when emitting child tuples, records the parent‑child relationship. Upon ack, the bolt sends an XOR of the parent tuple ID and its children’s IDs to the Acker. When the XOR result reaches zero, the entire tuple tree is considered successfully processed.

Spout task creates a tuple and registers {:spout-task task-id :val ack-val} with the Acker.

Bolt emits a child tuple and records the parent‑child link.

When a bolt acks, it computes tuple-id ^ (child-id1 ^ child-id2 … ^ child-idN) and sends it to the Acker.

The Acker XORs this value with the stored ack‑val; when the result is zero, the tuple tree is fully processed.

The Acker notifies the originating spout task of success or failure, triggering the spout’s ack or fail callbacks.

Storm Design: Component Abstractions

Topology : the logical representation of a distributed computation, composed of static components (spouts, bolts) and their stream groupings.

Spout : sources data from external systems into the Storm cluster.

Bolt : processes data, performing transformations, aggregations, etc.

Task : a runtime instance of a spout or bolt.

Worker : a JVM process that hosts one or more executors.

Executor : a thread that runs one or more tasks; multiple executors can share a worker.

Topology Parallelism Calculation

An example topology with two workers is shown below.

The code configuration (image) defines the number of workers, slots, and parallelism hints. The calculation proceeds as follows:

Total tasks: 2*1 + 4 + 6*1 = 12.

Runtime parallelism per worker: 10/2 = 5 executors per worker.

Distribute 12 tasks across 2 workers (5 executors each), aiming to keep same‑type tasks together.

Resulting distribution: each worker gets 3 yellow tasks, 2 green tasks, and 1 blue task.

Storm’s optimizer tries to co‑locate tasks of the same type on the same executor.

Storm Internal Principles

Each executor has an incoming and outgoing LMAX Disruptor queue.

Send threads move processed tuples to the outgoing queue; main threads pull from incoming queues and invoke task logic.

Workers contain a shared receive thread, an outgoing queue for inter‑worker tuples, and a transfer thread that ships tuples over the network.

Spout Task Inside an Executor

When a spout task runs alone in an executor, it reads data from its source, emits tuples, which the executor’s main thread places into the outgoing queue, and the send thread forwards them to downstream bolts.

Bolt Task Inside an Executor

A bolt executor contains both incoming and outgoing queues. Incoming tuples are taken by the main thread, processed by the bolt, and any emitted child tuples are placed into the outgoing queue for downstream bolts.

Tuple Transfer Within the Same Worker

When spout and bolt tasks reside in different executors of the same worker, tuples travel via the worker’s shared outgoing queue and transfer thread.

Tuple Transfer Across Different Workers

If the tasks are in separate workers (possibly on different supervisors), the transfer thread sends tuples over the network.

Tuple Routing Between Tasks

Each task has a unique topology‑wide identifier, enabling precise routing of tuples. The TaskMessage class (shown in the images) carries the tuple payload and destination task ID.

For example, a topology with three bolts (Bolt1, Bolt2, Bolt3) where Bolt1 has 2 tasks, Bolt2 has 2 tasks, and Bolt3 has 2 tasks demonstrates how tuples are routed based on task IDs across workers.

In summary, Storm’s architecture combines master‑slave coordination, flexible stream groupings, an acknowledgment system, and a hierarchy of tasks, executors, and workers to achieve reliable, real‑time distributed stream processing.

Source: 简单之美 (http://shiyanjun.cn/archives/1472.html). Contact information provided for removal requests.

distributed systemsbig dataStream ProcessingReal-time AnalyticsApache Storm
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.