Anatomy of a Flink cluster
Every Flink runtime consists of two types of processes: one JobManager and one or more TaskManagers../bin/flink run ....
The JobManager and TaskManagers can start in various ways: directly on machines as a standalone cluster, in containers, or managed by resource frameworks like YARN or Kubernetes. TaskManagers connect to the JobManager, announce themselves as available, and are assigned work.
JobManager
The JobManager coordinates the distributed execution of Flink applications. Its responsibilities include scheduling tasks, reacting to finished tasks or failures, coordinating checkpoints, and orchestrating recovery. It contains three distinct components:ResourceManager
ResourceManager
The ResourceManager handles resource de-allocation, allocation, and provisioning in a Flink cluster. It manages task slots — the unit of resource scheduling in Flink.Flink ships multiple ResourceManager implementations for different environments:
- YARN ResourceManager: requests and releases containers from YARN
- Kubernetes ResourceManager: starts and stops TaskManager pods
- Standalone ResourceManager: distributes slots of already-running TaskManagers; cannot start new ones on its own
Dispatcher
Dispatcher
The Dispatcher provides a REST interface for submitting Flink applications for execution. When a job is submitted, it starts a new JobMaster for that job. It also runs the Flink Web UI, which provides information about job execution, task status, metrics, and logs.
JobMaster
JobMaster
A JobMaster is responsible for managing the execution of a single JobGraph (the logical representation of a job). Multiple jobs can run simultaneously in a Flink cluster, each with its own JobMaster.In a high-availability setup, you can run multiple JobManagers: one acts as the leader and the others are on standby, ready to take over if the leader fails.
TaskManagers
TaskManagers (also called workers) execute the tasks of a dataflow and handle buffering and exchange of data streams between tasks. There must always be at least one TaskManager. Each TaskManager runs as a JVM process and may execute one or more subtasks in separate threads. The smallest unit of resource scheduling within a TaskManager is a task slot.Tasks and operator chains
For distributed execution, Flink chains operator subtasks together into tasks. Each task is executed by one thread. Chaining operators into tasks is a key optimization:- Reduces thread-to-thread handover overhead
- Eliminates intermediate buffering between chained operators
- Increases overall throughput
- Decreases end-to-end latency
map, a keyBy, a window, and a sink. Flink may chain the source and the map into a single task since they can share a thread without requiring repartitioning between them:
keyBy operator forces a network shuffle (repartitioning), which breaks the chain. Operators on either side of a shuffle boundary cannot be in the same chain.
Task slots and resources
Each task slot represents a fixed subset of resources of the TaskManager. A TaskManager with three slots, for example, dedicates 1/3 of its managed memory to each slot.Slots currently only separate managed memory between tasks. There is no CPU isolation — all slots on a TaskManager share the same CPU cores.
| Configuration | Behavior |
|---|---|
| 1 slot per TaskManager | Each task group runs in a separate JVM — maximum isolation |
| Multiple slots per TaskManager | Subtasks share the JVM, TCP connections, heartbeats, and data structures — lower overhead |
Slot sharing
By default, Flink allows subtasks from different operators of the same job to share a single slot. This means one slot can hold an entire pipeline of the job. Slot sharing provides two benefits:- Simpler capacity planning: A Flink cluster only needs as many task slots as the highest parallelism used in the job. You don’t need to count all tasks individually.
- Better resource utilization: Without slot sharing, lightweight operators like
source/map()would block as many slots as heavyweight operators likewindow. With slot sharing, resource-intensive and resource-light subtasks co-locate in the same slot, achieving better balance across TaskManagers.
Flink application execution
A Flink Application is any user program that spawns one or more Flink jobs from itsmain() method. The jobs can execute in:
- A local JVM via
LocalEnvironment(for development and testing) - A remote cluster via
RemoteEnvironment
ExecutionEnvironment (or StreamExecutionEnvironment) provides methods to control job execution such as setting parallelism, configuring state backends, and enabling checkpointing.
Cluster deployment modes
Flink offers three distinct deployment modes, each with different lifecycle and isolation guarantees:Flink Application Cluster
Flink Application Cluster
Lifecycle: Dedicated to a single Flink Application. The
main() method runs on the cluster itself (not the client), and the cluster shuts down when the application finishes. This is a one-step deployment: you package your application logic and dependencies into an executable JAR, and the ApplicationClusterEntryPoint calls main() to extract the JobGraph.Resource isolation: The ResourceManager and Dispatcher are scoped to a single application, which provides strong separation of concerns.Best for: Production deployments on Kubernetes where you want a clean, per-application lifecycle — similar to any other containerized application.Flink Session Cluster
Flink Session Cluster
Lifecycle: A long-running cluster that accepts multiple job submissions. The cluster keeps running even after all jobs finish — it lives until you manually stop it.Resource isolation: All jobs share the same cluster. TaskManager slots are allocated on job submission and released when the job finishes. If a TaskManager crashes, all jobs with tasks on that TaskManager fail.Best for: Interactive analysis or scenarios where job startup time must be minimized, since you avoid spinning up a new cluster per job.
Standalone cluster
Standalone cluster
Lifecycle: You manually start and manage the JobManager and TaskManager processes. Flink does not interact with any external resource manager.Best for: Simple setups, on-premise environments, or when you want full control over process placement.
YARN deployment
When running on YARN, Flink requests containers from the YARN ResourceManager. The Flink ResourceManager communicates with YARN to provision TaskManager containers on demand.Kubernetes deployment
Flink’s native Kubernetes integration allows Flink to directly communicate with the Kubernetes API server to manage TaskManager pods. This enables dynamic scaling and full lifecycle management without an intermediary resource manager.For high-availability setups, Flink can run multiple JobManagers where one is the elected leader and others are on standby. ZooKeeper or Kubernetes leader election is used to coordinate which JobManager is active.

