Learning Platform
Глоссарий Troubleshooting
Урок 03.02 · 16 мин
Средний
Deployment ModesApplication ModeSession ModePer-job Mode

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’ов. Полная изоляция.

Application mode: per-app cluster
Приложение 1Это ваш Java JAR с main() методом. main() вызывает env.execute(). Application mode: main() выполняется НА JobManager'е, не на клиенте.
submit, создаётся свой кластер

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 создаются автоматически.
другое приложение - другой кластер
Приложение 2Совершенно отдельное приложение со своим JAR. При submit создаётся свой JobManager и свои TaskManager'ы — никакой shared infrastructure.

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 mode: long-lived shared cluster

Session JobManager (long-lived)

Session JobManager: одна долгоживущая JVM. Принимает submit многих jobs (через REST API). Запускается заранее командой 'session start' или установкой Helm chart.
управляет всеми TaskManager'ами

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, но изоляция страдает.
submit jobs in sequence
Job ASubmit через REST API. Использует slots из shared pool. Когда заканчивается — slots возвращаются в pool.
Job BSubmit через REST API. Параллельно с job A — использует другие slots из pool. Job'ы могут конкурировать за ресурсы.
Job CЕщё один job. Если в pool недостаточно slots — job ждёт (PENDING state) пока другие jobs не завершатся.

Преимущества 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 это уже не существует.
WARNING

Если в 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 ModeSession Mode
Изоляция между jobsПолнаяНет (shared infra)
Накладные расходыВысокие (per-app cluster)Низкие (один cluster)
Cold startМедленный (10-30 с в K8s)Быстрый (cluster уже работает)
Где выполняется main()На JobManager’еНа клиенте
КейсыProduction стрим-jobsAd-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, нет автоскейлинга.


В современной K8s-инфраструктуре наиболее популярный путь — Flink Kubernetes Operator + Application mode.

Как Application mode реализован внутри

Операторская модель:

  1. Вы пишете FlinkDeployment CRD (YAML) с описанием приложения: образ, параллелизм, ресурсы, savepoint location.
  2. Применяете через kubectl apply -f my-app.yaml.
  3. Flink Operator (контроллер в кластере) видит CRD, создаёт JobManager Deployment + TaskManager Deployments.
  4. JobManager стартует, читает JAR из образа, запускает main(), submit’ит job.
  5. 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.


Попробуй сам

  1. Запустите job в Application mode локально. Стандартный docker compose из урока 00.3 запущен в Session mode. Для Application mode нужно использовать команду flink run-application -t local /path/to/jar. Заметьте отличия в Web UI: что новое, что одинаково?

  2. Откройте Web UI running job. Найдите “Job Manager” tab. В Application mode JobManager dedicated этому job; в Session mode он shared. Можно ли по UI понять, какой режим использовался?

  3. Прочитайте Flink Kubernetes Operator quickstart на сайте (https://nightlies.apache.org/flink/flink-kubernetes-operator-docs-stable/). Не нужно сейчас разворачивать — просто посмотрите на пример FlinkDeployment YAML и сопоставьте с тем, что вы знаете.

Проверка знанийKnowledge check
Команда выбирает deployment mode для production CDC pipeline на 50+ instances (каждый — для отдельного database tenant). Один из инженеров предлагает Session mode для экономии ресурсов: 'один кластер на всех тенантов'. Какие аргументы за и против, и какое решение правильное?
ОтветAnswer
За Session mode: меньше overhead JobManager'ов (один вместо 50), быстрый submit новых tenants, легче мониторить один кластер. Против: один глючный tenant может OOM'нуть TaskManager и положить ВСЕ 50 jobs; shared classloader конфликты возможны; failure blast radius — катастрофический; масштабирование сложно (для какого tenant нужно больше slots?); upgrade одного tenant требует cancel + restart, в Session mode это блокирует pool. Правильное решение: Application mode. 50 FlinkDeployment CRD, каждый со своими JobManager и TaskManager'ами. Полная изоляция, простой operational model, независимые upgrades через savepoint. Накладные расходы на 50 JobManager'ов оправданы изоляцией tenants. Если у вас 5000+ tenants — это другой случай (multi-tenancy patterns, beyond scope этого курса).

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 4. Главное архитектурное преимущество Application mode перед Session mode для production streaming jobs:

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 4