Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що потрібно, щоб застосунок у контейнерах можна було масштабувати горизонтально?

Горизонтальне масштабування - запустити кілька однакових контейнерів і розподіляти між ними запити. Працює, лише якщо контейнер без стану (stateless): будь-який запит може обробити будь-яка копія.

Що заважає масштабуванню і куди це винести:

Стан у контейнері Куди винести
сесії у файлах Redis чи база даних (SESSION_DRIVER=redis)
кеш у файлах Redis, Memcached
завантажені файли в storage/app об'єктне сховище (S3, R2) чи спільний том
черги в синхронному режимі чи database на SQLite Redis чи база даних, окремі воркери
планувальник у кожному контейнері окремий контейнер чи onOneServer()
блокування у файлах блокування через Redis/базу

Типові наслідки, якщо цього не зробити:

  • користувача «розлогінює» при кожному запиті - сесія на іншій копії;
  • завантажений аватар то є, то немає;
  • запланована задача виконується стільки разів, скільки контейнерів (листи - вчетверо);
  • кеш скидається лише на одній копії.

Масштабування в різних середовищах:

docker compose up -d --scale app=4          # кілька копій на одному сервері
docker service scale myapp_app=4             # Swarm
kubectl scale deployment app --replicas=4    # Kubernetes

На одному сервері кілька копій мають сенс, лише якщо одна копія не використовує всі ядра; справжня користь - копії на різних серверах за балансувальником.

Що ще враховувати:

  • з'єднання з базою: кожна копія тримає свій пул - 10 копій по 20 процесів PHP-FPM = 200 з'єднань. База може не витримати раніше, ніж закінчаться ресурси застосунку;
  • база - не масштабується так само: вузьке місце переміщується туди - репліки для читання, кеш, оптимізація запитів;
  • довірені проксі - за балансувальником застосунок має бачити справжні IP і протокол;
  • одноразові задачі при старті (міграції, прогрів кешу) не повинні виконуватися кожною копією.

Для Laravel контейнер з php-fpm чи FrankenPHP, сесіями й кешем у Redis, файлами в S3 і окремими контейнерами для воркерів і планувальника - класична конфігурація, що масштабується.

Докладніше в документації: Compose: deploy.replicas

Схожі питання