Celery в нагруженных проектах: немного практики

В преддверии нашей Moscow Python Conf++ мы кратко поговорили с Олегом Чуркиным, техлидом финтех-стартапа, о его обширном опыте работы с Celery: полмиллионе фоновых задачах, багах и тестировании.

9e704bf65f55a3ee6007034fc9a38540.jpg
— Расскажи немного деталей о проекте, над которым ты сейчас работаешь?

В данный момент я занимаюсь финтех-стартапом Statusmoney, который анализирует пользовательские финансовые данные и позволяет клиентам сравнивать свои доходы и расходы с другими группами людей, выставлять лимиты по тратам, наблюдать, как растет или падает благосостояние на графиках. Пока проект ориентирован только на североамериканский рынок.

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

Сейчас у нас около 200 тыс пользователей и 1,5 терабайта различных финансовых данных от наших поставщиков. Одних транзакций около 100 млн.

— А каков технологический стек?

Стек текущего проекта — это Python 3.6, Django/Celery и Amazon Web Services. Мы активно используем RDS и Aurora для хранения реляционных данных, ElasticCache для кэша и для очередей сообщений, CloudWatch, Prometheus и Grafana — для алертинга и мониторинга. Ну и, конечно, S3 для хранения файлов.

Мы также очень активно используем Celery для различных бизнес-задач: рассылки уведомлений и массовых рассылок писем, массового обновления различных данных из внешних сервисов, асинхронного API и тому подобного.

На фронтенде у нас React, Redux и TypeScript.

— Какой основной характер нагрузок в вашем проекте и как вы с ними
справляетесь?

Основная нагрузка в проекте ложится на фоновые задачи, которые исполняет Celery. Ежедневно мы запускаем около полумиллиона различных задач, например, обновление и процессинг (ETL) финансовых данных пользователей из различных банков, кредитных бюро и инвестиционных институтов. Помимо этого отсылаем много уведомлений и рассчитываем множество параметров для каждого пользователя.

Еще у нас реализован асинхронный API, который «пулит» результаты из внешних источников и также генерирует множество задач.

В данный момент, после тюнинга инфраструктуры и Celery, справляемся без проблем, но раньше бывало всякое, обязательно расскажу об этом в своем докладе.

— Как вы это всё масштабируете и обеспечиваете отказоустойчивость?

Для масштабирования мы используем Auto Scaling Groups — инструментарий, который предоставляет наша облачная платформа AWS. Django и Celery хорошо масштабируются горизонтально, мы только немного настроили лимиты на максимальное количество памяти используемой воркерами uWSGI/Celery.

— А мониторите чем?

Для мониторинга cpu/memory usage и доступности самих систем используем Cloud Watch в AWS, различные метрики из приложения и из Celery-воркеров агрегируем с помощью Prometheus, а строим графики и отправляем алерты в Grafana. Для некоторых данных в Grafana мы используем ELK как источник.

— Ты упоминал асинхронный API. Расскажи чуть подробнее, как он у вас
устроен.

У наших пользователей есть возможность «прилинковать» свой банковский (или любой другой финансовый) аккаунт и предоставить нам доступ ко всем своим транзакциям. Процесс «линковки» и обработки транзакций мы отображаем динамически на сайте, для этого используется обычный пулинг текущих результатов с бекенда, а бекенд забирает данные, запуская ETL pipeline из нескольких повторяющихся задач.

— Celery — продукт с противоречивой репутацией. Как вам с ним живется?

По моим ощущениям, наши отношения с Celery сейчас находятся на стадии «Принятие» — мы разобрались как фреймворк работает внутри, подобрали для себя настройки, разобрались с деплоем, «обложились» мониторингом и написали несколько библиотек для автоматизации рутинных задач. Некоторой функциональности нам не хватило «из коробки», и мы дописали ее самостоятельно. К сожалению, на момент выбора стека технологий для проекта, у Celery было не так много конкурентов, и если бы мы использовали более простые решения, то нам пришлось бы дописать намного больше.

С багами именно в четвертой версии Celery мы ни разу не сталкивались. Большинство проблем было связано либо с нашим непониманием того, как это все работает, либо со сторонними факторами.

О некоторых написанных внутри нашего проекта библиотеках я расскажу в своем выступлении.

— Мой любимый вопрос. Как вы всю эту музыку тестируете?

Задачи Celery хорошо тестируются функциональными тестами. Интеграцию тестируем с помощью автотестов и ручного тестирования на QA-стендах и стейджинге. На данный момент мы еще не решили пару вопросов с тестированием периодических задач: как позволять тестировщикам их запускать и как проверять, что расписание у этих задач корректное (соответствует требованиям)?

— А тесты на фронтенд и вёрстку? Какое вообще соотношение ручного и
автоматизированного тестирования?

На фронте мы используем Jest и пишем только юнит-тесты на бизнес-логику. 55% бизнес-критикал кейсов у нас сейчас покрыты автотестами на Selenium, на данный момент у нас около 600 тестов в TestRail и 3000 тестов на бекенде.

59f40fad7b54ad4abeb212461b6653a7.jpg

— О чем будет твой доклад на Moscow Python Conf ++ ?

В докладе я подробно расскажу, для каких задач и как можно использовать Celery, и сравню его с существующими конкурентами. Опишу, как можно избежать различных граблей при проектировании сложной системы с большим количеством задач: какие настройки стоит указать сразу, а какие можно оставить на потом, как задеплоить новую версию кода так, чтобы не потерять задачи при переключении трафика, поделюсь написанными библиотеками для мониторинга задач и очередей.

Также затрону тему реализации ETL-пайплайнов на Celery и отвечу, как описать их красиво, какую использовать retry policy, как гранулярно ограничивать количество выполняемых задач в условиях ограниченных ресурсов. Плюс опишу, какие инструменты мы используем для реализации пакетной обработки задач, которая экономно расходует доступную память.

В общем, если вы жаждите деталей по всем вышеобозначенным пунктам, приходите. Надеюсь, мой доклад покажется вам полезным и интересным.

© Habrahabr.ru