Параллелизм в Python
О чём курс
Артём Шумейко разбирает применение конкурентности и параллелизма в прикладной разработке на Python: от работы с GIL и корутинами до координации распределённых систем под высокой нагрузкой.
О чём курс
Материал ориентирован на решение инженерных проблем, возникающих в продакшене при росте нагрузки. Вместо синтетических учебных примеров разбираются ошибки в микросервисной архитектуре и проектируются компоненты для реальных сценариев: обработка потоков данных из Kafka, координация нескольких инстансов сервиса и трансляция событий через вебсокеты.
Для проверки архитектурных решений автор моделирует нагрузку до 1000 RPS, показывая узкие места сервисов и способы их оптимизации с помощью подходящих инструментов: потоков, процессов, очередей и распределённых блокировок.
Необходимая подготовка
Курс рассчитан на разработчиков, которые уже уверенно владеют базовым стеком:
- веб-фреймворком FastAPI;
- реляционной базой данных PostgreSQL;
- контейнеризацией в Docker;
- системой контроля версий Git.
Темы и технологии
Обучение охватывает шесть тематических блоков:
- Основы параллелизма: влияние GIL на IO-bound и CPU-bound задачи, внутреннее устройство событийного цикла, управление корутинами через Tasks, Futures, gather и TaskGroup;
- Взаимодействие с базой данных и API: потокобезопасность, coroutine-safe код в паттерне Repository, конкурентные вызовы к PostgreSQL без разделения одной сессии, таймауты и повторные попытки запросов;
- Распределённые системы: координация независимых воркеров, защита от проблемы thundering herd с помощью паттерна Single Flight, распределённые мьютексы и семафоры, обновление токенов и хранение состояния в памяти;
- Фоновые задачи: интеграция TaskIQ и Celery, паттерн Transactional outbox для защиты от рассинхронизации данных, вынос блокирующего кода в отдельные потоки;
- Очереди и потоковая обработка: локальные очереди asyncio.Queue, микросервис аналитики, агрегация и батчинг событий для записи в ClickHouse, перелив данных из брокера сообщений Kafka в Websocket в реальном времени;
- Профилирование и стабильность: перенос тяжёлых CPU-расчётов в ProcessPoolExecutor, отслеживание блокировок event loop, сквозной трейсинг запросов через contextvars и реализация graceful shutdown.
Формат
В тариф «Стандарт» входят все учебные материалы курса, включая лекции и практические домашние задания, а также участие в еженедельных встречах со спикером без индивидуальной проверки домашних работ.
Программа обучения
Неделя 1. Фундамент конкурентности и параллелизма
- Разбираем конкурентность и параллелизм по кирпичикам: как задействуются ядра процессора, как переключаются потоки, и как работают сокеты
- GIL, IO-bound и CPU-bound: что именно блокирует GIL, как он влияет на каждый тип нагрузки и почему CPU-bound задача не ускоряется от async
- Корутины и событийный цикл изнутри: почему это не просто "тупая" очередь задач, и как его не заблокировать
- Корутины, потоки, процессы, воркеры: разница, когда что выбрать
- Tasks и Futures: create_task, получение результата, обработка исключений, отмена и потеря задач
- gather и TaskGroup: как ведёт себя группа задач при падении одной из них и как безопасно запускать набор задач
- Домашнее задание: Сравнить последовательный и параллельный запуск корутин, получить блокировку event loop. Поработать с запуском и отменой задач. Вынести блокирующую функцию в поток, CPU-задачу — в процесс.
- Результат недели: Уложишь в голове, как устроены потоки, процессы, корутины и воркеры, разберёшься с базой асинхронности и, глядя на любую задачу или код, будешь сразу понимать, каким инструментом её решать.
Неделя 2. Работа с базой данных и внешними API под нагрузкой
- Знакомство с production-style микросервисом заказов: где в нём прячется конкурентность и что ломается под нагрузкой в первую очередь
- Как устроены большинство Python библиотек для работы с БД, Redis, брокером, и как не выстрелить себе в ногу при больших нагрузках
- Параллельные запросы к базе PostgreSQL: что такое thread-safe и coroutine-safe, и почему типичный паттерн Repository ломается в этом случае
- as_completed и wait: забираем результаты по мере готовности, не дожидаясь самого медленного
- Домашнее задание: Реализовать HTTP-клиенты к внешним API и параллельно подтягивать данные при создании события. На превью заказа параллельно собирать сущности из БД, не шаря одну сессию. Добавить таймауты, обработку ошибок и retry на временные ошибки.
- Результат недели: Научишься ходить в базу и внешние API параллельно, переиспользовать TCP-соединения и на реальных примерах увидишь, насколько это ускоряет сервис. Погрузишься в параллельные запросы, которые нужны каждый день, и поймёшь, какой код безопасно выполнять конкурентно.
Неделя 3. Координация в распределенной системе
- Что меняется, когда сервис живёт запущен в нескольких инстансах?
- Как согласовать всех воркеров, даже если они живут на разных серверах?
- Паттерн Single Flight: как из тысячи одинаковых запросов пропустить в базу только один (решение проблемы Thundering herd)
- Распределенная блокировка на примере протухшего токена: продлеваем общий токен внешнего API так, чтобы это сделал ровно один воркер, избежав 429 ошибок
- Состояние прямо в памяти приложения: когда кэша уже мало и приходится жертвовать оперативкой ради производительности
- Домашнее задание: Добавить Redis кэш и защитить популярное событие от лавины запросов через паттерн single flight через распределенную блокировку. Решить проблему thundering herd через распределенный мьютекс для обновления протухшего токена. Подтягивать snapshot конфига в память фоновой задачей.
- Результат недели: Шагнёшь в распределённые системы и начнёшь решать серьезные проблемы: удерживать базу под наплывом запросов, согласовывать состояние между воркерами и не дать им наперегонки атаковать общий ресурс или внешний API.
Неделя 4. Фоновые задачи. От простых методов до production-ready
- TaskIQ и Celery: когда задачу пора отдавать воркеру и чем опасны фоновые задачи
- Как снизить нагрузку на сервис, используя поллинг для длинных
- Паттерн Transactional outbox: как не допустить расхождения данных между базой, taskiq/celery и приложением
- Как ускорить асинхронное приложение через вынос блокирующего кода в потоки. Учимся распознавать такой код
- Домашнее задание: Вынести обработку покупок в Taskiq, отдавая статус для поллинга. Регулярно проверять билет и обновлять статус. Генерировать QR-код синхронным SDK во внешнем потоке.
- Результат недели: Познакомишься с самыми популярными инструментами для фоновых задач в Python и поймёшь, какие проблемы с ними связаны. Научишься сам выбирать инструмент под задачу: когда выносить CPU-нагрузку, когда I/O и что для этого взять.
Неделя 5. Очереди, батчинг и потоковая обработка событий из Kafka
- Зачем использовать очередь asyncio.Queue внутри приложения
- Батчинг событий в ClickHouse: как снизить нагрузку с базы в сотни раз
- Как действовать, если не успеваешь обрабатывать входящий поток сообщений из брокера
- Знакомимся со вторым микросервисом аналитики, с получением тысяч событий из Kafka
- Как выстроить пайплайн по переливу данных из Kafka в Websocket для рил-тайм слежения за курьерами на карте
- Домашнее задание: Отправлять аналитику в фоновом режиме, чтобы запрос её не ждал. Копить события в очереди и писать в ClickHouse батчами. Обрабатывать данные из Kafka.
- Результат недели: Научишься работать с Kafka асинхронно и с вебсокетами, делать батчинг данных и не перегружать базу, что критично важно на продакшене.
Неделя 6. Профилирование и трейсинг Python приложений
- Выносим CPU-нагрузку правильно: какие вычисления отпускают GIL и почему от этого зависит выбор между потоками и процессами
- Тяжёлый отчёт уезжает в воркер: клиент опрашивает статус и забирает готовый файл
- CPU-расчёты по перемещениям курьеров и генерация Excel — в ProcessPoolExecutor, чтобы сервис не замирал
- Ловим блокировки event loop: лаги, медленные коллбеки и охота за тем, что подвешивает сервис
- Трейсинг сквозного запроса через contextvars: видим весь путь запроса, даже когда всё перемешано в логах
- Graceful shutdown: гасим сервис с фоновыми задачами, очередями и воркерами без потери данных
- Домашнее задание: Реализовать запуск отчёта о продажах через Taskiq с поллингом и скачиванием файла. Собрать аналитику по продажам и сгенерировать Excel отчет, вынеся CPU-вычисление в процесс. Добавить мониторинг блокировок event loop и трейсинг.
- Результат недели: Разберёшься, как правильно выносить CPU-нагрузку, и научишься профилировать и трейсить асинхронный код, находя узкие места под нагрузкой.
Теги курса
Отзывов пока нет. Будьте первым!
Этот курс сейчас в процессе организации складчины. Нажмите кнопку «Записаться» и ожидайте старта — вам придёт уведомление. Когда складчина стартует, в карточке курса будет указан актуальный взнос. Текущая цена пока в процессе формирования и может отличаться от финальной.
Да, мы стремимся, чтобы финальный взнос был не больше ≈10% от оригинальной цены курса. Чем больше участников записывается в складчину, тем ниже выходит взнос для каждого.
Нажмите кнопку «Записаться» и авторизуйтесь на сайте через email (через ту же почту, которую будете использовать для входа). В личном кабинете вас будут ждать инструкции, как пригласить других участников — чем больше людей записалось, тем быстрее стартует складчина и тем ниже взнос. Как только складчина готова к приобретению, вам придёт уведомление.