Distributed and fault-tolerant realtime computation

What is Trident in Storm?

Last reviewed:

Trident is a higher-level API on top of Storm that processes streams in small batches and updates state exactly once. It arrived in Storm 0.8.0 in August 2012. You describe a pipeline with operations such as each, groupBy and persistentAggregate, and Trident compiles it into ordinary spouts and bolts that run on the same cluster as any other topology.

A first example

This is the word count from the Trident tutorial. It splits sentences into words, groups by word and keeps a running count per word:

TridentTopology topology = new TridentTopology();
TridentState wordCounts =
    topology.newStream("spout1", spout)
        .each(new Fields("sentence"), new Split(), new Fields("word"))
        .groupBy(new Fields("word"))
        .persistentAggregate(new MemoryMapState.Factory(), new Count(), new Fields("count"))
        .parallelismHint(6);

Written as a plain Storm topology, the same job needs a splitting bolt, a fields grouping, a counting bolt and code that writes counts to a store and copes with replays. In Trident the count is a TridentState object. MemoryMapState keeps it in memory for testing, and other state implementations keep it in databases such as Cassandra, HBase or Redis.

The operations

How Trident updates state exactly once

Trident groups incoming tuples into batches and gives each batch a transaction id. Batches can be processed in parallel, but state updates are committed in transaction-id order. Each stored value is saved along with the id of the batch that last changed it. If a batch fails and is replayed, Trident compares ids: when the stored id already matches the batch, the update was applied before and is skipped. A count therefore never goes up twice for the same tuple, even though Storm underneath may replay it.

How strong the guarantee is depends on the spout:

The Apache Storm documentation covers these in detail on its Trident state page.

Queries with DRPC

Trident can also answer requests through Storm's distributed RPC. A DRPC stream takes a query, looks up the keys it needs in a TridentState with stateQuery, and returns the combined answer. In the tutorial, the same word counts built above answer "how many times have these words appeared?" in parallel across the cluster.

Costs and trade-offs

Batching adds latency, because a tuple waits for its batch to be committed. Trident also has more moving parts than a plain topology, and a topology with many operations compiles into bolts that are harder to trace in the Storm UI. For stateless work such as filtering or routing, a plain topology with at-least-once processing is simpler and faster.

Trident today

Trident still ships with Apache Storm under the org.apache.storm.trident package. It was storm.trident before Storm 1.0. Storm 2.0 added a separate typed Streams API for writing topologies in a functional style. Other systems reached exactly-once in different ways later: Flink with distributed checkpoints and Kafka Streams with Kafka transactions. The Storm vs Flink page compares the approaches. For the full API, see the Trident tutorial and the Trident API overview.