Flink, simulated
An animated Flink job in your browser: Kafka partitions feeding chained operators, keyBy through key groups, event-time windows driven by watermarks, keyed state on HashMap or RocksDB, checkpoint barriers (aligned and unaligned), failure and recovery, a two-phase-commit Kafka sink, backpressure and rescaling from a savepoint — with guided scenarios, a key-group calculator and a window explorer.
Added
How to use it
A Flink streaming job in miniature that runs entirely in this page: a Kafka topic, a source,
keyBy, a window (or a keyed process function) and a sink, deployed as parallel subtasks on
TaskManager slots under a JobManager. Every record, watermark, checkpoint barrier, credit,
acknowledgement and commit is a labelled packet on the diagram, and the rules — which window a
record belongs to and when it fires, which subtask owns a key, when a barrier blocks a channel,
what is restored after a failure and what a read_committed consumer sees — follow Flink’s own.
Nothing here talks to a real cluster.
How to use it
Pick a scenario and press Start. Each step does something — changes the job, pauses a partition, kills a TaskManager, takes a savepoint — then plays until what the narration describes has happened and pauses so you can read. Next step moves on, Back rewinds (the simulator is deterministic, so it replays the earlier steps), ⏭ jumps to the end of the step and Step ⇥ advances to the next single thing that happens. Space plays and pauses; → is the next step. Every step links to the Flink documentation or paper that explains it. The Playground scenario has no script: build a pipeline under Pipeline and cluster settings and feed it events.
Speed and Hop time set the pace. At 1× the simulated clock runs in real time. Hop time is how long checkpoint traffic (triggers, barriers, acknowledgements, notifications, commits) and failure messages take to cross the diagram at 1×; while one is on its way the clock slows. The steady flow of records and watermarks is never slowed. Sim clock turns the slowing off. Hop time changes only how the run is shown, never what happens.
⛶ Full screen (or F) gives the diagram the whole window; Esc leaves. In full screen the stats, watermarks, output, checkpoints and event log sit in a side panel that ▤ Panels (or [) shows and hides; on a phone the panel opens under the diagram.
-
The diagram. The JobManager at the top (job status, the CheckpointCoordinator’s current or last checkpoint, attempts and restarts); the Kafka topic on the left with each partition’s end offset, read offset and lag (⏸ when watermark alignment paused it); one box per subtask, column by column (source → window or process → sink; chained operators share one box); the sink’s output on the right; and the TaskManagers with their slots at the bottom. A subtask shows its watermark, a busy / backpressured / idle bar (ms per second, as the web UI reports them), what it reads or which key groups it owns and how many keys and windows it holds, and one gauge per input channel — its buffers filling up (red when out of credit), ⏸ while blocked by checkpoint alignment, ↯ while its in-flight data is being persisted for an unaligned checkpoint. Records travel the channels coloured by key (labelled
key@event timewhen traffic is light), watermarks asW, barriers as a black bar labelledCP n, credits as small green dots going back, and the JobManager’s triggers, acknowledgements, notifications and restores in violet. Tap anything to inspect it and act on it. -
Stats. Job status, records read, windows fired, results visible to the consumer, uncommitted results, duplicates, late records dropped or sent to the side output, expired state, checkpoints, the last checkpoint’s duration and alignment (or persisted in-flight records), restarts and the highest backpressure.
-
Watermarks. For every subtask, the last watermark of each input (split or channel) and the resulting minimum.
-
Output. What a consumer sees (with
read_committed, only committed transactions), the whole topic log (open, pre-committed, aborted records too), and the late side output. -
Checkpoints. Recent checkpoints and savepoints: trigger time, duration, size (incremental and full for RocksDB), alignment time or persisted in-flight records, and the Kafka offsets stored.
-
Keyed state. Each window subtask’s key-group range and its state: windows per key with their aggregate (✓ when fired), or the ValueState counter with its age and TTL.
-
Kafka partitions. End offset, read offset, lag and which source subtask reads each partition.
-
Do something. Send an event with any key, partition and event time (now, out of order, late); pause or resume a partition; trigger a checkpoint; stop with a savepoint; rescale; kill a TaskManager; switch to unaligned checkpoints, idleness or a
read_uncommittedconsumer. -
Settings rebuild the job: window type, size, slide, gap, allowed lateness, side output, aggregate, a filter, time characteristic, watermark bound, idleness, alignment, parallelism of each operator, max parallelism, slots, chaining, state backend, TTL, checkpoint interval and mode, sink, consumer isolation, the topic’s partitions, rate, keys, disorder and late records, and per-record costs. Each shows Flink’s default.
The other tabs: Key groups computes, for any keys, Java’s hashCode(), MathUtils.murmurHash,
the key group and the owning subtask at two parallelisms (which keys move on rescaling), the
key-group ranges, and the default max parallelism. The Window explorer takes events (key and
event time) in arrival order and shows which tumbling, sliding or session windows they fall into,
when each fires for a given out-of-orderness bound, late firings within the allowed lateness and
the records dropped as late.
What it models
-
Kafka source (FLIP-27, Kafka connector): partitions are splits assigned to readers as
KafkaSourceEnumerator.getSplitOwnerdoes —((topic.hashCode() × 31) & 0x7FFFFFFF) % readers, then round-robin; per-split watermarks; offsets in checkpoints, committed back to Kafka only for monitoring; earliest or latest starting offsets for new jobs. -
Watermarks (generating watermarks):
forBoundedOutOfOrderness(max timestamp − bound − 1 ms) emitted everypipeline.auto-watermark-interval(200 ms); a reader’s watermark is the minimum over its active splits;withIdlenessmarks quiet splits idle and sends WatermarkStatus.IDLE; an operator’s watermark is the minimum over its non-idle input channels; watermark alignment (FLIP-182) pauses splits ahead of the group’s slowest by more than the allowed drift. -
Windows (windows): tumbling and sliding assigners with
TimeWindow.getWindowStartWithOffset, session windows merged withTimeWindow.mergeWindows(touching windows merge), EventTimeTrigger (fire when the watermark reaches end − 1 ms; fire at once for a late element of a live window), cleanup at end − 1 + allowed lateness,numLateRecordsDroppedandsideOutputLateData; processing-time windows on the clock. The window model follows Akidau et al., The Dataflow Model (VLDB 2015). -
Keyed state and key groups:
KeyGroupRangeAssignment— key group =MathUtils.murmurHash(key.hashCode()) % maxParallelism, owner = key group × parallelism / max parallelism, contiguous ranges[⌈i·M/p⌉, ⌊((i+1)·M − 1)/p⌋], default max parallelism min(max(nextPowerOfTwo(p + p/2), 128), 32768) — checked against Flink 1.20’s own classes. ValueState with TTL (OnCreateAndWrite, NeverReturnExpired, cleanup in full snapshots). State backends (docs): HashMap (objects on the heap) and RocksDB (serialized, slower access, incremental checkpoints). -
Network stack: credit-based flow control — a channel gets
buffers-per-channelexclusive buffers plus a share offloating-buffers-per-gate; a sender sends only with credit; full output buffers block the producing task, which is how backpressure propagates back to the sources and into Kafka lag (network stack deep-dive, back pressure). -
Checkpoints: asynchronous barrier snapshots (Carbone et al., Lightweight Asynchronous Snapshots for Distributed Dataflows, 2015), a variant of Chandy and Lamport’s distributed snapshots (1985): the coordinator triggers the sources, which snapshot their offsets and inject barriers; aligned barriers block a channel until all inputs' barriers arrive; unaligned barriers (FLIP-76) overtake buffered data, which is persisted as channel state; tasks acknowledge after the asynchronous upload; the coordinator completes the checkpoint and notifies every task.
-
Recovery: a lost TaskManager is detected after the heartbeat timeout; the whole pipelined region restarts after the restart delay; state, Kafka offsets and (for unaligned checkpoints) in-flight data are restored from the last completed checkpoint. A plain sink then writes replayed results again; the exactly-once KafkaSink (two-phase commit: pre-commit on the barrier, commit on
notifyCheckpointComplete, commit-or-abort on recovery) never exposes them toread_committedconsumers. -
Savepoints and rescaling: stop with a savepoint, restart with another parallelism; key groups are redistributed in contiguous ranges; a parallelism above the max parallelism is refused.
Limits
-
One pipeline shape: Kafka source (with an optional filter) → keyBy → one window or keyed process function → sink. No joins, CEP, SQL, broadcast state, iterations or async I/O operators (the backpressure scenario models async I/O as a lower per-record cost).
-
Records are individual events at modest rates; costs are fixed per record; buffers hold a fixed number of records; the network has a fixed latency; checkpoint uploads have a fixed speed.
-
Timeouts are much shorter than Flink’s defaults (heartbeat 50 s, restart delay 1 s, checkpoint timeout 10 min — each setting shows the default). No high availability, no region failover for disconnected graphs, no checkpoint storage, no changelog state backend, no buffer debloating.
-
Duplicates are judged by result identity (key, window, firing). A new job started by a scenario step writes to a fresh view of the output.
Linking to an example
Links can be written by hand. Add a tab after #: sim (the default), keygroups or windows.
A link’s settings replace this page’s saved settings (a button restores yours).
| Parameter | Meaning | Example |
|---|---|---|
|
A scenario (list below), with its own settings; parameters given with it override the scenario’s |
|
|
The same, without the scenario’s own settings being written into the link |
|
|
Kafka partitions, 1–6 |
|
|
Records per second per partition |
|
|
Distinct keys, 1–8 |
|
|
Records are out of order by up to this many ms |
|
|
Every n-th record is late (0: none) |
|
|
How late, in ms |
|
|
Source parallelism, 1–4 |
|
|
Window / process parallelism, 1–4 |
|
|
Sink parallelism, 1–4 |
|
|
Max parallelism (number of key groups) |
|
|
Chain operators where possible |
|
|
|
|
|
|
|
|
Window size in ms |
|
|
Slide in ms (sliding windows) |
|
|
Session gap in ms |
|
|
Allowed lateness in ms |
|
|
Send late records to a side output |
|
|
Watermark out-of-orderness bound in ms |
|
|
withIdleness in ms (0: off) |
|
|
Watermark alignment max drift in ms (0: off) |
|
|
|
|
|
State TTL in ms (keyed counter only; 0: off) |
|
|
Checkpoint interval in ms (0: off) |
|
|
|
|
|
|
|
|
The consumer’s |
|
|
Window / process cost per record in ms |
|
|
Random seed |
|
|
Playback speed: |
|
|
Hop time in seconds (0.1–5) or |
|
Scenarios:
example= |
Shows |
|---|---|
|
Processing-time vs event-time windows on the same records; reproducible event-time results (open) |
|
Bounded out-of-orderness, the minimum across inputs, an idle partition stalling every window, withIdleness, watermark alignment (open) |
|
Tumbling, sliding and session windows; late records dropped, re-fired with allowed lateness, or sent to a side output (open) |
|
Keyed state per key group, state TTL, HashMap vs RocksDB, incremental checkpoints (open) |
|
Barriers, alignment, acknowledgements and completion; unaligned checkpoints (open) |
|
A lost TaskManager, restart from the last checkpoint, Kafka offsets rewound, duplicates in an at-least-once sink (open) |
|
A two-phase-commit Kafka sink: pre-commit on the barrier, commit on completion, abort on failure, read_committed without duplicates (open) |
|
Credit-based flow control, backpressure up to Kafka lag, slow aligned checkpoints, unaligned ones, fixing the bottleneck (open) |
|
Key groups, stop with savepoint, restore at a new parallelism, the max-parallelism limit (open) |
|
Your own pipeline and events (open) |
Feedback is a gift. Something to improve, a feature to add, or a bug? Tell me.
Runs entirely in your browser; nothing you type leaves this page.