Зачем устанавливать максимальный для каждого задания Apache Flink, для чего stateful-оператору пользовательский UUID, как выбрать подходящий бэкенд хранения состояний, от чего зависит оптимальный интервал создания контрольных точек и где настраивается высокая доступность менеджера заданий.
5 главных настроек перед запуском Flink-приложения в производственное развертывание
Перед запуском приложения Apache Flink в производственное использование необходимо проверить и настроить параметры конфигурации, чтобы максимально эффективно использовать возможности фреймворка и среду развертывания. Особенно важными параметрами конфигурации являются следующие:
- максимальный параллелизм для каждого задания и оператора, что определяет возможность масштабирования stateful-операторов и производительность приложения;
- уникальные идентификаторы для всех операторов, необходимые для сопоставления состояний операторов Flink с операторами, что, в свою очередь, важно для точек сохранения;
- наиболее подходящий бэкенд хранения состояний stateful-операторов, о чем мы писали здесь;
- оптимальный интервал контрольных точек, который будет соответствовать компромиссу между скоростью и надежностью обработки данных, нагрузки и толерантности к дублям/потерям;
- настройка высокой доступности менеджера заданий (JobManager), что мы подробно рассматривали здесь.
Apache Flink является фреймворком для stateful-вычислений над неограниченными и ограниченными потоками данных, поддерживая состояния операторов, т.е. события или промежуточные результаты, необходимые для последующей обработки. Состояние приложения управляется и контролируется подключаемым бэкендом – сервером состояния, который хранит состояние в памяти или во встроенном key-value хранилище RocksDB. Также можно подключить пользовательские бэкэнды состояний. Согласованность и отказоустойчивость состояния в случае сбоя обеспечивают механизмы контрольных точек и точек сохранения Flink. Flink может поддерживать состояния размером в несколько терабайт благодаря асинхронному и инкрементному механизму контрольных точек. Также фреймворк поддерживает масштабирование stateful-приложений путем перераспределения состояния между большим или меньшим количеством рабочих процессов.
Чтобы предотвратить потерю данных в случае сбоя, серверная часть (backend) состояния периодически сохраняет моментальный снимок своего содержимого в предварительно настроенном долговременном хранилище в памяти или на диске файловой системы: MemoryStateBackend, RocksDBStateBackend, FsStateBackend. Подходящий backend состояния для развертывания в производственной среде зависит от требований к масштабируемости, пропускной способности и задержке. К примеру, MemoryStateBackend и FsStateBackend основаны на области памяти, называемой кучей (heap) JVM, где хранится текущее состояние stateful-приложения. MemoryStateBackend рекомендуется для локальных разработок и отладки, а не для использования в производственной среде. FsStateBackend работает достаточно быстро, поскольку информация о состоянии хранится непосредственно в JVM, что исключает временные затраты на сериализацию и десериализацию данных. Обычно для stateful-приложений Apache Flink используется RocksDBStateBackend на основе встраиваемой key-value NoSQL-СУБД RocksDB, однако, в облачном управляемом сервисе Flink на платформе Ververica Cloud вместо этого используется GeminiStateBackend. Этот механизм хранения значений ключа предназначен для оптимизации производительности потоковой обработки данных благодаря возможности гибко и адаптивно настроить параметры хранилища для разных операторов.
Из-за ориентированности Apache Flink на разработку stateful-приложений, для их оптимального развертывания в производственной среде важно настроить максимальный параллелизм, до которого может масштабироваться оператор с состоянием. В настоящее время невозможно изменить максимальный параллелизм оператора после запуска задания, не отбрасывая его состояние. Flink должен поддерживать определенные метаданные, чтобы масштабировать состояние, которое растет линейно с максимальным параллелизмом. Поэтому следует выбирать максимальный параллелизм, достаточно высокий, чтобы соответствовать потребностям в масштабировании, но при этом сохранять его достаточно низким для поддержания разумной производительности. Разработчик Flink-приложения может явно установить максимальный параллелизм, используя метод setMaxParallelism(int maxparallelism). Если максимальный параллелизм не установлен, Flink установит его при первом запуске задания по умолчанию равным 128.
Чтобы повысить прозрачность мониторинга состояний stateful-операторов, следует для каждого из них установить пользовательский уникальный идентификатор — UUID. Это необходимо для сопоставления состояний операторов Flink и важно для точек сохранения. По умолчанию идентификаторы операторов генерируются путем прохождения JobGraph и хеширования определенных свойств оператора. Хотя автоматическая генерация UUID удобна для пользователя, любые изменения в JobGraph, например, замена оператора, приводят к появлению новых идентификаторов. Поэтому для более контролируемой разработки и отладки нужно установить стабильное сопоставление, используя стабильные идентификаторы операторов, предоставляемые пользователем через метод setUid(String uid).
Также перед запуском Flink-приложения в производство необходимо настроить интервалы создания контрольных точек. Контрольные точки — это основной механизм отказоустойчивости Flink, когда моментальный снимок состояния задания периодически сохраняется в надежном месте. В случае сбоя приложение перезапустится с последней контрольной точки и возобновит обработку. Интервал контрольной точки заданий определяет, как часто Flink будет делать эти снимки. При выборе интервала рекомендуется учитывать следующие аспекты:
- соглашение об уровне обслуживания сервиса (SLA, Service Level Agreement) и период целевой точки восстановления (RPO, Recovery Point Objective) — максимальный период за который могут быть потеряны данные. Например, если задание завершится сбоем за секунду до следующей контрольной точки, какой объем данных можно перенести на повторную обработку? Интервал контрольной точки в 5 минут означает, что Flink никогда не будет повторно обрабатывать данные за период более 5 минут после сбоя.
- периодичность и надежность поставки результатов. Например, некоторые приемники, такие как Apache Kafka или файлоые приемники (FileSink), делают результаты видимыми только после завершения контрольной точки. Более короткие интервалы между контрольными точками позволяют быстрее получать результаты, но могут создать дополнительную нагрузку на системы-приемники. Важно найти такое время доставки, которое будет соответствовать требованиям, не создавая чрезмерную нагрузку на приемники результатов вычислений из Apache Flink.
- мощность диспетчеров задач, т.е. какую нагрузку они могут выдержать. Поскольку все встроенные серверные функции Flink поддерживают асинхронную контрольную точку, процесс моментального снимка не приостанавливает обработку данных, но потребляет вычислительные ресурсы ЦП и пропускную способность сети. Чтобы снизить стоимость создания контрольных точек, их можно создавать инкрементально, добавляя новые данные к ранее сохраненному состоянию.
Наконец, для обеспечения высокой доступности Flink-приложений следует настроить JobManager, который служит центральным координатором каждого развертывания, отвечая за планирование и управление ресурсами кластера. Это единственная точка отказа внутри кластера, и в случае ее сбоя новые задания не могут быть отправлены на исполнение, а работающие приложения завершатся сбоем. Для обеспечения высокой доступности используется Apache Zookeeper или Kubernetes, которые управляют метаданными и ускоряют восстановление узлов кластера Flink.
Узнайте больше про использование Apache Flink для потоковой обработки событий в распределенных приложениях аналитики больших данных и машинного обучения на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:
Источники