JavaRush /Курси /Модуль 4: FastAPI /Основи паралельної обробки завдань у системах

Основи паралельної обробки завдань у системах

Модуль 4: FastAPI
Рівень 14 , Лекція 0
Відкрита

Паралельна обробка завдань — це як наявність кількох касирів для обслуговування черги в супермаркеті або банку. У такому підході кількох клієнтів обслуговують одночасно, що скорочує час очікування в черзі. У програмуванні все точно так само.

У світі застосунків ми стикаємося з такими задачами, як обробка запитів користувачів, виконання складних обчислень і обробка даних. Якщо виконувати все це послідовно, то продуктивність системи різко постраждає. У таких випадках паралельна обробка стає ключовим елементом для підвищення ефективності.


Паралельна vs послідовна обробка

У послідовній обробці кожне завдання виконується одне за одним. Наприклад:


def process_tasks_sequentially(tasks):
    for task in tasks:
        perform_task(task)

Всі завдання тут виконуються послідовно, і жодне не починається, поки не завершиться попереднє. Підходить для простих і не критичних по часу систем, але явно не для високонавантажених застосунків.

А от так виглядає паралельна обробка:


from concurrent.futures import ThreadPoolExecutor

def process_tasks_in_parallel(tasks):
    with ThreadPoolExecutor() as executor:
        results = executor.map(perform_task, tasks)

За допомогою ThreadPoolExecutor ми можемо одночасно запускати обробку завдань. Це дозволяє розподілити навантаження і прискорити виконання.


Де застосовується паралельна обробка?

  1. Обробка зображень: наприклад, у вас є сервіс, який дозволяє користувачам завантажувати фотографії, а ви застосовуєте фільтри або якісь ваші "магічні" алгоритми обробки. Якщо обробляти кожну фотографію послідовно, користувачам доведеться чекати, поки кожен знімок буде оброблений.
  2. Обробка повідомлень: у системах реального часу (наприклад, у чатах чи на ігрових серверах) повідомлення мають оброблятися максимально швидко, інакше користувачі будуть незадоволені.
  3. Аналітика великих даних: коли ваш бос хоче звіт по всіх продажах за останні п'ять років прямо зараз (а це мільярд записів), ясно, що послідовний підхід — шлях до звільнення. Паралельна обробка — порятунок.

Риби, птахи і RabbitMQ: роль брокерів у паралельності

Щоб організувати паралельну обробку завдань, вам потрібен інструмент, який буде розподіляти завдання між робочими процесами (воркерами). Тут на сцену виходить RabbitMQ.

RabbitMQ — це система черг повідомлень, яка дозволяє розподілити завдання між кількома воркерами. Паралельна обробка у зв'язці RabbitMQ + Celery виглядає приблизно так:

  1. Завдання поміщається у чергу RabbitMQ.
  2. Один з воркерів забирає завдання з черги.
  3. Воркери працюють паралельно, обробляючи різні завдання.

А чому б не просто покласти все в одну чергу? Уявіть, що у вас є лише один касир (воркер), який намагається обслуговувати чергу з тисячі людей. Це занадто повільно.


Різниця між паралельною та асинхронною обробкою

Так-так, я чую ваші думки: "А хіба асинхронна обробка — це не паралельна?". Близько, але трохи не те.

  • Асинхронна обробка дозволяє виконувати інші задачі, поки поточна задача "чекає" (наприклад, мережа або диск).
  • Паралельна обробка означає виконання кількох задач одночасно, використовуючи кілька потоків або процесів.

Приклад асинхронного коду в Python:


import asyncio

async def perform_task(task):
    print(f"Starting {task}")
    await asyncio.sleep(2)  # Імітуємо довгу операцію
    print(f"Completed {task}")

async def main():
    await asyncio.gather(perform_task("Task 1"), perform_task("Task 2"))

asyncio.run(main())

Цей код уміє "чекати" завершення однієї задачі, поки виконується інша. Однак якщо ви хочете реальної паралельності, вам потрібні або процеси (multiprocessing), або потоки (threading).


Як почати паралельну обробку завдань?

Паралельну обробку краще довірити інструментам, які вже себе зарекомендували. Наприклад:

  • Celery: бібліотека для управління задачами, яка підтримує паралельну обробку прямо "з коробки".
  • RabbitMQ: використовується як брокер повідомлень для розподілу завдань.

Коли ми задіюємо зв'язку RabbitMQ + Celery, робочий процес виглядає так:

  1. Завдання надсилаються в Celery.
  2. Celery передає їх RabbitMQ для розподілу.
  3. Кілька воркерів (workers) обробляють задачі паралельно.

Практичний приклад

Давайте розглянемо, як налаштувати паралельну обробку на простому проєкті з використанням Celery.

Спочатку встановимо Celery і RabbitMQ:


pip install celery

Тепер налаштуйте RabbitMQ. Якщо у вас Docker, це можна зробити за допомогою команди:


docker run -d --hostname my-rabbit --name some-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:management

Конфігурація Celery

Створіть файл celery_app.py:


from celery import Celery

# Конфігурація Celery
celery_app = Celery('tasks', backend='rpc://', broker='pyamqp://guest@localhost//')

@celery_app.task
def add(x, y):
    return x + y

Тепер запустимо Celery воркерів:


celery -A celery_app worker --loglevel=info

Надішлемо задачу в чергу. Виконаємо задачу, яка порахує суму:


from celery_app import add

result = add.delay(4, 6)  # Відправляємо задачу в чергу
print(result.get())       # Очікуємо результат

Воркери виконають задачу паралельно, якщо ви запустите кілька екземплярів воркерів.


Типові труднощі

Іноді здається, що все йде добре, але потім... бінг! Проблеми:

  1. "Черга переповнилася": якщо воркери не встигають обробляти задачі, черга почне роздуватися. Це сигнал про те, що треба або додати воркерів, або оптимізувати задачі.
  2. Перехресні залежності задач: іноді одна задача може залежати від іншої. Відстежуйте залежності, щоб уникнути конфліктів.
  3. Перевитрата ресурсів: занадто багато воркерів можуть завалити сервер. Знайдіть баланс між кількістю воркерів і доступними ресурсами.

Ми тільки почали розкручувати маховик паралельної обробки. У наступних лекціях ви дізнаєтесь, як налаштувати Celery для ефективної обробки задач і оптимізувати роботу RabbitMQ для великих навантажень. Уперед до обробки задач зі швидкістю світла!

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ