Весна богата на новые релизы: в начале мая 2022 года вышел Apache Flink 1.15. Рассказываем, что нового в свежем выпуске: краткий обзор самых полезных фич для разработчика распределенных приложений, а также интересные изменения, исправления ошибок и улучшения для дата-инженера.
Scala под капотом и спецификация REST API по стандарту OpenAPI
Apache Flink растет и развивается, добавляя все новые возможности к прежним вариантам использования. В частности, в новом релизе 1.15 сделан еще один шаг в сторону low code/no-code, чтобы снизить дата-аналитикам порог входа в эту технологию, предлагая им расширенные функции SQL вместо программирования на Java и Scala. Теперь можно обновлять задания SQL без потери состояния благодаря поддержке механизма контрольных точек после завершения задач и оконных функции в пакетном режиме. В новой версии оконные табличные функции могут быть реализованы с помощью специального оператора, который больше не обязательной агрегации. Также полезна возможность работы с данными JSON в SQL: пользователи могут проверять, создавать и изменять строки JSON с помощью диалекта Flink SQL.
Разработчиков Flink-приложений порадует возможность использования Java API из любой версии Scala. При этом им не придется беспокоиться о путях к нужным классам и зависимостях: Scala теперь под капотом фреймворка. Язык по-прежнему существует в кодовой базе, но больше не просачивается в загрузчик классов пользовательского кода.
Напомним, раньше могли возникать различные коллизии из-за предоставления пользователям всех зависимостей, т.к. в каждом пути к классам мог существовать только один экземпляр файла класса, нужный JVM для загрузки и работы приложения. При этом Flink продолжает использовать Scala в нескольких ключевых компонентах, включая стек сериализации, RPC и планировщик таблиц. Однако, в версии 1.15 все зависимости Scala изолированы в JAR-архиве flink-scala. Чтобы удалить Scala из пути к классам пользовательского кода, нужно удалить этот JAR-файл из каталога lib дистрибутива Flink. В будущем Flink продолжит поддерживать пакеты Scala для API-интерфейсов DataStream и Table, скомпилированных для Scala 2.12 вместо API Java, чтобы пользователи могли использовать компоненты из любой версии Scala.
Также для разработчиков распределенных приложений пригодится спецификация REST API по стандарту OpenAPI в новой версии Flink. Еще улучшены восстановление и очистка заданий, запущенных в режиме приложения: локальное состояние может сохраняться в рабочем каталоге, что упрощает восстановление из локального хранилища. Наконец, в Apache Flink 1.15 улучшено совместное использование интерфейсов потоковой и пакетной обработки.
Контрольные точки и точки сохранения
Следует отдельно рассказать про упрощение механизма контрольных точек и точек сохранения: он стал более прозрачен, упрощая автоматическое масштабирование за счет устранения побочных эффектов, когда разные источники данных производят разные объемы данных. Кроме того, теперь есть возможность обновлять задания SQL без потери состояния. Напомним, отказоустойчивость Flink-приложений основана на checkpoints и savepoints, о чем мы писали здесь. Цель точек сохранения в том, чтобы пользователи могли контролировать переходы, резервное копирование и обновление заданий Flink. Контрольные точки нужны для полного контроля Flink и гарантируют отказоустойчивость за счет быстрого восстановления, отработки отказа и т. д. Обе концепции очень похожи, и базовая реализация также разделяет аспекты одних и тех же идей. Однако, некоторые нюансы их различаются, что вызывало путаницу. Например, пользователь полагались на контрольные точки для остановки и перезапуска заданий, хотя более корректно было применение точек сохранения. Более того, было неочевидно, что точки сохранения работают медленнее из-за отсутствия некоторых функций. Подробнее про проблемы контрольных точек и способы их решения читайте в нашей новой статье.
В версии 1.15 эти недостатки исправлены, сохранив поддержку собственных и добавочных точек сохранения: теперь пользователи могут использовать собственный формат для получения savepoint, а также бэкэнд состояния RocksDB, где они будут автоматически создаваться поэтапно. Также уточнена семантика возобновления с точки сохранения и сохраненной контрольной точки, введены режимы CLAIM и NO_CLAIM. В режиме CLAIM Flink берет на себя владение существующим моментальным снимком, а в режиме NO_CLAIM (по умолчанию) создает собственную копию и оставляет существующую на усмотрение пользователя. Старая семантика возобновления с точки сохранения/сохраненной контрольной точки по-прежнему доступна, но ее необходимо выбирать вручную, выбрав режим LEGACY.
В отличие от предыдущего релиза, в Flink 1.15 конечные контрольные точки включены умолчанию. Это изменение в конфигурации может продлить последовательность закрытия ограниченных потоковых заданий, поскольку они должны ждать последней контрольной точки, прежде чем могут завершиться. Таким образом, при запуске Flink в режиме приложения можно гарантировать, что задания получат точку сохранения после их завершения, если они были настроены для этого.
Наконец, обновление контрольных точек улучшает потоковую обработку событий, снижая сквозную задержку, особенно для приемников транзакций. Транзакционные приемники фиксируются на контрольных точках, поэтому более быстрые контрольные точки означают более частые фиксации. Интервалы контрольных точек стали более предсказуемыми, т.к. их время зависит от размера артефактов, которые необходимо сохранять в хранилище checkpoint’ов. Регулярное сохранение данных небольшого размера делает время создания контрольных точек более предсказуемым. Это также полезно при восстановлении: чем чаще выполняются контрольные точки, тем меньше данных требуется повторно обрабатывать после каждого восстановления. Все это реализовано в бэкенде лога изменений, обеспечивая постоянное сохранение изменений состояния в энергонезависимой памяти при материализации состояния в фоновом режиме. Подробнее об этом читайте в нашей новой статье.
Эластичное масштабирование с коннекторами, реактивным режимом и адаптивным планировщиком
В Apache Flink 1.15 улучшен реактивный режим для заданий, где JobManager может использовать все доступные ресурсы TaskManager, учитывая все метрики в Job scope. Это ускоряет масштабирование: TaskManager теперь имеет выделенный путь кода выключения, где он активно отменяет регистрацию в кластере вместо отсчета тактовых импульсов. Таким образом, JobManager оперативно получает четкий сигнал для уменьшения масштаба.
Для использования Flink с облачной инфраструктурой в релиз 1.15 добавлен восстанавливаемый модуль записи для Google Cloud Storage. Также улучшены коннекторы к экосистеме AWS (KDS, Firehose). Дополнительно стоит выделить приемник Elasticsearch, реализованный с новыми интерфейсами коннекторов, которые предлагают асинхронную функциональность в сочетании со сквозной семантикой. Этот приемник будет выступать в качестве типового шаблона для будущих решений.
Также добавлена история исключений для нового адаптивного планировщика, который сначала объявляет требуемые ресурсы и ожидает их, прежде чем принять решение о параллелизме для выполнения задания. В версии 1.15 реализован AdaptiveBatchScheduler, который может автоматически определять параллелизм вершин пакетных заданий в зависимости от объема обрабатываемых данных.
Основные преимущества нового пакетного адаптивного планировщика:
- простота использования – пользователям пакетных заданий не нужно настраивать параллелизм самостоятельно;
- адаптивность — автоматически настраиваемые параллелизмы лучше соответствуют используемым наборам данных с меняющимся объемом;
- гранулярность – параллелизм каждой вершины задания настраивается индивидуально, позволяя автоматически назначать вершинам пакетных SQL-заданий различные степени параллелизма;
- выравнивание водяных знаков по источникам данных, т.к. они могут увеличивать отметку watermark с разной скоростью, что приводит к проблемам с нижестоящими операторами. Например, некоторым операторам может потребоваться буферизация чрезмерных объемов данных, увеличивая состояние оператора.
Чем адаптивный пакетный планировщик отличается от потокового, читайте в нашей новой статье. Также в Apache Flink 1.15 можно активировать выравнивание водяных знаков для источников данных. Пользователи могут определить группы выравнивания, чтобы приостановить потребление из источников, которые намного опережают другие.
Новинки Flink SQL
В Apache Flink план выполнения SQL-запросов и его результирующая топология основаны на правилах оптимизации и модели затрат, поэтому даже минимальные изменения могут привести к совершенно другой топологии. Эта динамика делает очень сложной задачу обеспечения совместимости моментальных снимков в разных версиях Flink. В версии 1.15 один и тот же запрос сохраняет свою топологию даже после обновлений.
Теперь в основе обновлений SQL лежат планы JSON, которые представляют собой функции JSON, упрощающие импорт и экспорт структурированных данных в SQL. Это введено для внутреннего использования уже в предыдущих релизах и теперь доступно для внешних пользователей. И Table API, и SQL предоставляют способ компилировать и выполнять план, который гарантирует одинаковую топологию в разных версиях. Пока функция выпущена в экспериментальном режиме, но ее уже можно попробовать, создав план JSON, который затем можно использовать для восстановления задания Flink на основе старой структуры оператора. Полная реализация ожидается в релизе 1.16.
Таким образом, эти обновления делают Flink SQL более надежным для производственных сценариев использования в долгосрочной перспективе. Кроме того, улучшено приведение типов: теперь поведение по умолчанию при сбое типа CAST изменилось с возврата Null-значения на возврат ошибки, что делает его более совместимым со стандартом SQL. Старое поведение приведения по-прежнему можно использовать, вызвав недавно введенную функцию TRY_CAST, или восстановить с помощью флага конфигурации.
Улучшение PyFlink
До Flink 1.15 UDF-функции Python выполнялись в отдельных процессах Python, что приводило к дополнительным затратам на сериализацию/десериализацию и обмен данными. В случае с большими объемами данных, например, обработка изображений, эти накладные расходы становились весьма существенными. Кроме того, имело место межпроцессное взаимодействие, увеличивая задержку обработки, что неприемлемо в транзакционных и других real-time сценариях. В Flink 1.15 реализован новый режим выполнения под названием «режим потока», для которого UDF-функции Python выполняются в JVM как поток вместо отдельного процесса Python. Тестирование этого решение показало, что пропускная способность может быть увеличена в 2 раза в таких сценариях как обработка JSON, а задержка обработки снижается с секунд до микросекунд. Пока этот первый выпуск режима потока поддерживает только Python ScalarFunction, который используется в Python Table API и SQL. В будущем разработчики Flink планируют расширить этот режим на другие области UDF-функций Python.
Узнайте больше про Apache Flink и Spark для потоковой обработки событий в распределенных приложениях аналитики больших данных на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:
- Потоковая обработка данных с помощью Apache Flink
- Hadoop для инженеров данных
- Потоковая обработка в Apache Spark