Deployment modes: Application, Session, что устарело
Flink можно запускать в кластере по-разному. Решение об этом — одно из первых и важных, потому что оно определяет isolation, resource utilization, и operational complexity. В Flink 2.x ландшафт упростился: остались два режима — Application mode (рекомендуемый default) и Session mode. Третий, Per-job mode, который был популярен в 1.x, окончательно удалён в 2.0.
К концу урока вы будете уметь выбирать deployment mode осознанно и понимать, что увидите в чужом legacy-проекте.
Application mode: один job — один кластер
В Application mode каждое приложение получает свой собственный JobManager. Это означает: один job — один JobManager — свой набор TaskManager’ов. Полная изоляция.
JobManager 1 (per-app)
JobManager 1: создан специально для этого приложения. main() выполняется здесь. JobMaster координирует один job — ваш.TM 1.1
TaskManager dedicated этому приложению. Не делится с другими jobs. Изоляция ресурсов.TM 1.2
TaskManager 2 для приложения 1. Количество TM соответствует parallelism job.TM 1.3
TaskManager 3 для приложения 1. В Native K8s mode TaskManager pods создаются автоматически.JobManager 2 (per-app)
JobManager 2: совершенно отдельный JVM, своя память, свой failure domain. Если JobManager 1 упал — приложение 2 не пострадает.TM 2.1
TM 2.1: dedicated приложению 2. Не shared с приложением 1. Изолированные ресурсы.TM 2.2
TM 2.2: второй TaskManager для приложения 2. Изолированный failure domain.Преимущества Application mode:
- Полная изоляция: проблемы одного приложения (OOM, slow checkpoints, hot keys) не затрагивают другие.
- Простая модель: один app = один Deployment в Kubernetes. Легко мониторить, легко жёстко скейлить, легко удалить.
- Чистый lifecycle: app остановлен — JobManager и TaskManager pods удалены. Никаких “висящих” ресурсов.
- main() выполняется на JobManager’е: значит, dependencies вашего main()-кода (например, чтение конфига из Vault) выполняются in-cluster, не на клиенте.
- Идеален для Flink Kubernetes Operator: FlinkDeployment CRD = одна Application mode деплой.
Недостатки:
- Накладные расходы: каждое приложение требует свой JobManager (минимум 1 GB JVM). Для очень маленьких jobs может быть избыточно.
- Долгий cold start: при submit нового app — создание JobManager pod + TaskManager pods. Это 10-30 секунд в K8s.
Когда использовать: для большинства production случаев это default. Особенно для долгоживущих стрим-приложений (CDC pipelines, real-time aggregations).
Как запустить в Application mode
В Standalone (docker compose):
docker exec -it flink-jobmanager flink run-application \
-t local \
/opt/flink/examples/streaming/WordCount.jar
В Native Kubernetes:
flink run-application \
-t kubernetes-application \
-Dkubernetes.cluster-id=my-app \
-Dkubernetes.container.image=my-flink:2.2 \
local:///opt/flink/usrlib/my-app.jar
(В большинстве случаев вы не вызываете flink run-application вручную — это делает Flink Kubernetes Operator через FlinkDeployment CRD.)
Session mode: shared кластер для многих jobs
В Session mode заранее создаётся долгоживущий кластер (JobManager + TaskManager’ы), и в него можно сабмитить много jobs. Все jobs делят инфраструктуру.
Session JobManager (long-lived)
Session JobManager: одна долгоживущая JVM. Принимает submit многих jobs (через REST API). Запускается заранее командой 'session start' или установкой Helm chart.Shared TM 1 (slots для всех jobs)
Shared TaskManager 1: его slots распределяются между сабмитнутыми jobs. Если job A использует 4 slot, job B — 2 slot, осталось столько-то для job C.Shared TM 2
Shared TaskManager 2: те же слоты, доступны всем jobs. Дешевле — нет per-job overhead, но изоляция страдает.Преимущества Session mode:
- Низкие накладные расходы: один JobManager на много jobs. Cold start новых jobs быстрый — кластер уже работает.
- Ad-hoc jobs: удобно для batch-style processing, экспериментов, аналитических запросов через SQL Client.
- Простое управление: один кластер мониторить вместо многих.
Недостатки:
- Нет изоляции: один глючный job может OOM’нуть TaskManager, отвалив все jobs на нём.
- Shared classloader проблемы: дёрнули несовместимые библиотеки в двух jobs — конфликты.
- Bad blast radius: JobManager падает = все jobs останавливаются.
- Тяжело автоматически скейлить: scaling решения сложнее (для какого job нужно больше slots?).
Когда использовать:
- Ad-hoc batch и аналитика: SQL Client с короткими запросами.
- Маленькие jobs: где per-job JobManager overhead неприемлем.
- Разработка: локальная разработка, эксперименты.
Когда НЕ использовать: production стрим-приложения, которые должны быть изолированными. Для них — Application mode.
Как запустить в Session mode
В Standalone — наш docker compose из урока 00.3 это уже Session mode! JobManager долгоживущий, TaskManager’ы зарегистрированы статически, мы submit’им jobs через flink run.
В Native Kubernetes:
# Стартовать session cluster
flink kubernetes-session.sh \
-Dkubernetes.cluster-id=my-session \
-Dkubernetes.container.image=flink:2.2
# Затем sabbit jobs
flink run -t kubernetes-session \
-Dkubernetes.cluster-id=my-session \
/path/to/my-job.jar
Per-job mode: что это было и почему его нет
Per-job mode в 1.x был промежуточным режимом между Application и Session:
- Каждый submit job создавал свой JobManager (как в Application mode).
- НО main() выполнялся НА КЛИЕНТЕ (не на JobManager) — как в Session mode.
- main() строил JobGraph, отправлял в свежесозданный JobManager.
Проблемы Per-job mode:
- main() на клиенте: клиент должен иметь все dependencies. В Kubernetes это не natural fit — что такое “клиент” в K8s?
- Дублирование логики: и Application, и Per-job делали изолированные кластеры; разница только в том, где main() выполняется.
- Confusion для новичков: три mode’а с тонкими различиями.
Что произошло в 2.0: Per-job mode удалён. Сообщество решило, что Application mode достаточен (он покрывает все use case Per-job mode и работает чище в Kubernetes).
Что это значит для вас:
- Если у вас Flink 1.x с командой
flink run -m kubernetes-per-job ...— это deprecated. Мигрируйте на Application mode перед апгрейдом на 2.x. - Если читаете старый туториал и видите “per-job mode” — знайте, что в 2.x это уже не существует.
Если в legacy 1.x коде есть flink run (без -application) — по умолчанию это Per-job mode (или Session, в зависимости от target). В 2.x команды изменились: flink run-application для Application mode, flink run -t kubernetes-session для Session mode. Старые скрипты могут перестать работать.
Сравнительная таблица
| Свойство | Application Mode | Session Mode |
|---|---|---|
| Изоляция между jobs | Полная | Нет (shared infra) |
| Накладные расходы | Высокие (per-app cluster) | Низкие (один cluster) |
| Cold start | Медленный (10-30 с в K8s) | Быстрый (cluster уже работает) |
| Где выполняется main() | На JobManager’е | На клиенте |
| Кейсы | Production стрим-jobs | Ad-hoc batch, SQL Client, dev |
| Скейлинг | На уровне job (Operator) | На уровне cluster (вручную) |
| Failure blast radius | Один job | Все jobs в session |
| Default в 2.x | Да | Опция |
Какой выбрать в production
В 2026 году большинство production деплойментов следуют такому паттерну:
Application mode для каждого критичного streaming-приложения. Один CDC pipeline = одна FlinkDeployment CRD = один Application mode кластер. Это даёт изоляцию, простой operational model, и хорошо ложится в GitOps.
Session mode опционально для:
- Внутренней аналитической команды, которая запускает много ad-hoc SQL-запросов через SQL Client.
- Dev/staging кластеров для быстрых экспериментов.
- Batch-like processing с короткими jobs, где per-job overhead избыточен.
Standalone (docker compose как у нас) — только для разработки. Никаких production деплойментов в Standalone — нет HA, нет автоскейлинга.
Application mode + Flink Kubernetes Operator: state of the art
В современной K8s-инфраструктуре наиболее популярный путь — Flink Kubernetes Operator + Application mode.
Как Application mode реализован внутриОператорская модель:
- Вы пишете FlinkDeployment CRD (YAML) с описанием приложения: образ, параллелизм, ресурсы, savepoint location.
- Применяете через
kubectl apply -f my-app.yaml. - Flink Operator (контроллер в кластере) видит CRD, создаёт JobManager Deployment + TaskManager Deployments.
- JobManager стартует, читает JAR из образа, запускает main(), submit’ит job.
- Operator мониторит health, делает auto-scaling, обрабатывает upgrades через savepoint.
Пример FlinkDeployment (упрощённый):
apiVersion: flink.apache.org/v1beta1
kind: FlinkDeployment
metadata:
name: my-cdc-pipeline
spec:
image: my-registry/my-cdc:v1.2.3
flinkVersion: v2_2
flinkConfiguration:
state.savepoints.dir: s3://my-bucket/savepoints
state.checkpoints.dir: s3://my-bucket/checkpoints
serviceAccount: flink
jobManager:
resource:
memory: "2g"
cpu: 1
taskManager:
resource:
memory: "4g"
cpu: 2
replicas: 4
job:
jarURI: local:///opt/flink/usrlib/my-cdc.jar
parallelism: 8
upgradeMode: savepoint
Это покрывается deeply в модуле 15. Сейчас важно понимать: Application mode + Operator — это стандарт 2026 года для production.
Попробуй сам
-
Запустите job в Application mode локально. Стандартный docker compose из урока 00.3 запущен в Session mode. Для Application mode нужно использовать команду
flink run-application -t local /path/to/jar. Заметьте отличия в Web UI: что новое, что одинаково? -
Откройте Web UI running job. Найдите “Job Manager” tab. В Application mode JobManager dedicated этому job; в Session mode он shared. Можно ли по UI понять, какой режим использовался?
-
Прочитайте Flink Kubernetes Operator quickstart на сайте (https://nightlies.apache.org/flink/flink-kubernetes-operator-docs-stable/). Не нужно сейчас разворачивать — просто посмотрите на пример FlinkDeployment YAML и сопоставьте с тем, что вы знаете.