Всем привет! Меня зовут Артемий, я работаю SRE-инженером в команде RTP (real time processing) Clickstream в Авито. Сегодня мы хотим поделиться нашей историей о том, как мы переехали в Kubernetes, развернув Apache Flink с помощью Flink k8s operator.

В прошлой статье я также рассказал о FlinkSQL в Авито: этот материал поможет составить более полное представление о работе нашей команды.

Содержание:

Что такое Clickstream?

Clickstream — это система сбора, обработки и транспорта событий, генерируемых пользователями при взаимодействии с сервисами Авито. Каждый клик, просмотр страницы или другое действие создают аналитические события, которые мы собираем и анализируем. Эти данные помогают лучше понимать поведение пользователей, проводить A/B-тесты, получать инсайты и принимать более обоснованные решения.

Wisdom Soft Solutions
Wisdom Soft Solutions

Наша команда специализируется на обработке потока этих событий, то есть обработке данных по мере их поступления без временных задержек. Для этого необходимы инструменты, способные быстро и эффективно справляться с большими объёмами информации. Например, у нас это до миллиона событий в секунду из 500+ источников, а в день — это терабайты информации.

Тут еще больше контента

Почему Apache Flink?

Для обработки потоковых данных мы выбрали Apache Flink — передовую платформу с открытым исходным кодом, которая сочетает возможности анализа данных в реальном времени с гибкостью и надежностью масштабируемой архитектуры. Flink обрабатывает каждое событие по мере его поступления, обеспечивая минимальную задержку и мгновенную реакцию на действия пользователей.

Этот подход, называемый real-time processing, делает платформу особенно ценной в сценариях, где точность и своевременность обработки критически важны.

Вот несколько примеров из наших реальных use-cases «крупными мазками»: противодействие ботной активности, antifraud, персонализация контента, маркетинговые компании, модерации контента.

Flink Deployment Patterns
Flink Deployment Patterns

Ключевым компонентом Flink является его распределённая архитектура, построенная на взаимодействии двух типов узлов JobManager и TaskManager. JobManager отвечает за координацию выполнения задач, включая управление распределением ресурсов, планирование задач и отслеживание состояния выполнения. TaskManager, в свою очередь, выполняет обработку данных, обрабатывая конкретные подзадачи (tasks), и взаимодействует с JobManager для синхронизации. Такое разделение ролей обеспечивает высокую производительность и отказоустойчивость системы.

Flink предлагает два основных режима работы:

  1. Session Mode: здесь ресурсы и процессы JobManager и TaskManager разделяются между несколькими заданиями Flink (Jobs).

  2. Application Mode: здесь, напротив, каждая задача запускается с выделенными кластером, включая собственный JobManager, что упрощает управление и изоляцию.

Одной из уникальных возможностей Flink является поддержка состояния (stateful processing), что позволяет сохранять промежуточные результаты выполнения задач. А это дает дополнительные возможности для глубокого анализа потока данных.

Благодаря распределенной архитектуре и интеграции с такими инструментами, как Kafka, Cassandra, Hadoop и другие, Flink легко встраивается в имеющуюся архитектуру. Такие компании, как Uber, Netflix и Alibaba, уже используют Flink для решения ключевых задач в аналитике данных в реальном времени:

  • например, Uber применяет Flink для мониторинга и оптимизации маршрутов, анализа поведения водителей и пассажиров, а также предотвращения мошенничества в режиме реального времени.

  • Netflix использует Flink для п��рсонализации контента, отслеживания качества потокового видео и анализа пользовательских действий, что позволяет улучшать рекомендации и поддерживать высокий уровень пользовательского опыта.

  • Alibaba внедрила Flink для обработки огромных объёмов данных в своей экосистеме электронной коммерции, обеспечивая точный анализ транзакций, управление рекламными кампаниями и поддержку в проведении распродаж с аналитикой в реальном времени.

Как было раньше

Ранее наша инфраструктура для обработки Clickstream-данных строилась на использовании LXC-контейнеров и единого Session-кластера Flink. Такой подход оказался не лишён серьезных недостатков, которые со временем становились всё более заметными. В рамках Session-кластера все задачи Flink совместно использовали одни и те же ресурсы, что приводило к конкуренции за них. Нагрузка на одну задачу могла существенно снизить производительность других, создавая непредсказуемое поведение системы.

Отсутствие изоляции также стало одной из ключевых проблем. Если одна задача потребляла ресурсы сверх ожиданий или вызывала ошибки, что приводило к перегрузке всей ноды, вплоть до её падения. В результате стабильность всей системы оказывалась под угрозой, а восстановление требовало значительного времени и усилий. Тут важно понимать, что скорость восстановления системы является очень важным недостатком, поскольку в момент, когда одно или несколько заданий Flink не работают, начинает накапливаться очередь событий во входящей потоке (лаг) с одной стороны и отставание в выходящих данных с другой, что негативно сказывается на качестве предоставляемого сервиса.

Ещё одной серьёзной трудностью стало обновление компонентов кластера и интеграция с процессами CI/CD. Реализация инфраструктуры как кода (IaC) в существующей системе была сложной задачей, требующей значительных усилий на настройку, тестирование и развёртывание. Эти сложности увеличивали операционные затраты, снижали гибкость команды и создавали риски для стабильности системы, особенно в условиях высокой динамики развития продукта.

Поддержка такой инфраструктуры требовала недюжинных человеческих ресурсов — от настройки и мониторинга до устранения сбоев и оптимизации работы. Всё это создавало узкие места в масштабировании и увеличивало операционные затраты.

Жми сюда!

Переход на Kubernetes и Flink Kubernetes Operator

Чтобы решить существующие проблемы с нашей инфраструктурой, мы приняли решение перенести систему в Kubernetes. Для этого мы первыми в Авито развернули Kubernetes-кластер, работающий в трех датацентрах одновременно. Такая архитектура обеспечивает не только высокую доступность, но и оптимальную производительность, позволяя минимизировать задержки при обработке данных и гарантировать отказоустойчивость даже в случае выхода из строя одного из дата центров.

Для управления Flink-кластерами в этой новой среде мы выбрали Flink Kubernetes Operator, который идеально подошел для решения наших задач благодаря своей функциональности и глубокому взаимодействию с экосистемой Kubernetes. Оператор предоставляет декларативный подход к управлению кластерами Flink, органично вписываясь в наш подход к инфраструктуре и обеспечивая предсказуемость, автоматизацию и простоту развертывания.

Flink Kubernetes Operator — это open source расширение Kubernetes, которое разработано в рамках проекта Apache Flink, основанное на концепции Custom Resource Definition (CRD).

Оно позволяет управлять жизненным циклом Flink-кластеров, используя декларативный подход, который органично вписывается в Kubernetes. Благодаря чему мы получили возможность описывать состояние изолированных кластеров Flink в виде YAML-манифестов.

Под капотом оператор работает через расширение API Kubernetes, добавляя новые типы ресурсов — FlinkDeployment, что дает набор очень крутых плюсов. Начнем с того, что Flink Kubernetes Operator поддерживает создание, обновление и удаление кластеров Flink, а также автоматическое восстановление их работы при сбоях, что уменьшает сложность управления и исключило риски, связанные с ручным вмешательством. Также конфигурация кластера, включая настройки ресурсов, стратегию обновлений и параметры задач, описывается в одном месте и в понятном формате Yaml.

Благодаря возможностям Kubernetes каждое приложение работает в своей изолированной среде, что решает сразу комплекс проблем — например, в одном кластере k8s мы можем запустить сразу несколько кластеров с разными версиями Flink. Flink Kubernetes Operator поддерживает оба режима работы Flink — Session и Application, позволяя нам выбирать подходящий в зависимости от нагрузки и требований.

Благодаря Flink Kubernetes Operator мы смогли органично интегрироваться с ArgoCD, что дало возможность автоматизировать создание и обновление Flink-кластеров в рамках пайплайнов CI/CD, включая проверку соответствия манифестов и откат изменений в случае непредвиденных ошибок. Это значительно упростило процесс развёртывания, сделало его более предсказуемым и существенно сократило время выпуска обновлений. Кроме того, унификация подхода к управлению инфраструктурой через Argo CD укрепила контроль над версиями и снизила вероятность человеческих ошибок.

Также немаловажно, что, перейдя на Flink Kubernetes Operator в k8s, мы получили возможность удобно управлять ресурсами (речь о RAM и CPU), благодаря чему мы смогли намного более четко рассчитывать затрачиваемые ресурсы. Точное измерение и мониторинг использования ресурсов нативными механизмами k8s улучшили процессы биллинга. Теперь мы можем с высокой точностью прогнозировать затраты на инфраструктуру и эффективно планировать её масштабирование. Наличие детализированных метрик позволяет оптимизировать распределение ресурсов и избежать непредвиденных расходов, что особенно важно для долгосрочного роста и стабильности системы.

Кликни здесь и узнаешь

Заключение или как оно работает сегодня

В текущей конфигурации наша инфраструктура обрабатывает задачи Flink в крупном Kubernetes-кластере (~80 машин, ~60 кластеров flink, ~1500 подов), который распределен между тремя датацентрами. 

Мы активно используем метки и правила affinity/anti-affinity для оптимального распределения нагрузки между серверами. Это позволяет учитывать производительность оборудования, избегать конкуренции за ресурсы и поддерживать балансировку даже при увеличении нагрузки. Например, мы можем назначать более требовательные задачи на узлы с высокой производительностью или изолировать их от менее ресурсоемких приложений.

Для доставки секретов мы интегрировались с HashiCorp Vault используя init-контейнеры. Каждый Flink-кластер автоматически получает доступ к необходимым секретам, включая пароли и ключи доступа, без риска утечки данных.

Мы используем возможности Kubernetes для распределения TaskManager-ов, обеспечивая либо максимальную производительность, либо повышенную отказоустойчивость, в зависимости от требований конкретных задач. Например, благодаря удобному контролю за размещением TaskManager-ов, мы можем аккумулировать их в одном датацентре, чтобы избежать дорого и медленного трафика между ними (датацентрами).

Сбор логов и метрик Flink-кластеров интегрировано с нашей системой логирования, что позволяет в реальном времени отслеживать производительность, выявлять аномалии и анализировать инциденты. Логи доступны в удобном формате в централизованном хранилище, что значительно упрощает работу с ними.

Эксперименты и изменения теперь проводятся быстрее и с меньшими рисками благодаря интеграции CI/CD процессов в Kubernetes с Flink Kubernetes Operator. Автоматизация развертывания через Argo CD, поддержка декларативных манифестов и высокая предсказуемость поведения инфраструктуры сделали процесс доставки изменений прозрачным, что позволило не только сократить трудозатраты на внедрение новых фич, но и ускорить их выпуск.

Как вам улучшения? Был ли у вас похожий опыт переезда? Делитесь историями в комментариях.

А если хотите вместе с нами адаптироваться в мире стремительно развивающихся технологий — присоединяйтесь к командам. Свежие вакансии есть на нашем карьерном сайте.