Build stateful chain for different events and assign global ID in spark
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Apache Spark can maintain per-key state across streaming events, but assigning a true global chain ID requires careful design. The practical pattern is to group all related events by a stable business key, keep chain state with mapGroupsWithState or flatMapGroupsWithState, and create the chain ID once when the first event for that key arrives.
First decide what the chain key really is
Before writing Spark code, define the key that identifies "the same chain". Examples might be:
- a customer ID
- a session ID
- an order ID
- a correlation ID shared across event types
If different event types belong to the same logical chain, they must be normalized onto the same grouping key. Without that, Spark cannot keep the state together.
Use Structured Streaming state, not ad hoc IDs
For modern Spark streaming jobs, flatMapGroupsWithState is usually the right API. It lets you read the previous state for a key, update it with new events, and emit enriched output rows.
Simplified Scala example:
Then the state update function can initialize the chain once:
This gives every event for the same chainKey the same chainId.
Wire it into the streaming query
The important part is that state is scoped by the grouping key. That is how Spark remembers the chain between micro-batches.
Why monotonically_increasing_id() is not the answer
It is common to reach for monotonically_increasing_id() when the problem statement says "global ID". That is usually wrong for stateful chains.
Reasons:
- it is not stable across reprocessing
- it is generated per row, not per logical chain
- it does not naturally preserve a consistent ID for later related events
If you need one chain ID per business entity over time, you need state or an external mapping, not a one-shot row ID function.
When Spark state is not enough
If chains can merge, split, or be discovered across different keys later, simple per-key state may not be sufficient. In those cases, you may need:
- an external key-to-chain-ID store
- a deduplication or reconciliation step
- a deterministic chain ID derived from business logic
Spark can hold state per key very well, but it is not magic. The data model still has to make the chain observable.
Operational concerns
Stateful streaming means you also need to think about:
- checkpointing
- state store size
- late data and event-time ordering
- timeout and cleanup of old chains
A correct stateful chain design is not just about the update function. It is also about how the state grows and expires in production.
Common Pitfalls
- Using a row-level ID function when the requirement is a stable chain-level identifier.
- Grouping different event types by different keys and then expecting one shared state object.
- Ignoring event ordering when chain transitions depend on sequence.
- Forgetting checkpointing, which breaks state recovery after restart.
- Letting state grow forever because no timeout or cleanup policy exists.
Summary
- Define a stable business key that groups all events belonging to the same chain.
- Use
flatMapGroupsWithStateormapGroupsWithStateto persist chain state across batches. - Create the chain ID once when the state is first initialized for that key.
- Do not use
monotonically_increasing_id()as a substitute for persistent chain identity. - Plan for checkpointing, ordering, and state cleanup from the start.
Related reading
- Can a model be created on Spark batch and use it in Spark streaming?
- Can I create an RDD from a kafka topic if I do not know the until offset?
- Can I extract fp-tree (any format) in spark?
- Can Kafka streams deal with joining streams efficiently?
- Cannot launch SparkPi example on Kubernetes Spark 2.4.0
- Cannot process data using Spark Continuous Streaming
- Capture Kubernetes Spark driver and executor logs in S3 and view in History Server
- Caret train rf model - how long it takes to execute big data?

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.