Кластеризація серверів застосувань, балансування навантаження, шардинг даних, регіональні підрозділи.
До 5–10 тисяч активних користувачів UBD працює на одному правильно налаштованому сервері. Понад це — потрібна горизонтальна архітектура. Стаття описує, коли і як переходити від single-server до кластера, і де очікувати проблем.
| Параметр | Вертикальне (більший сервер) | Горизонтальне (більше серверів) |
|---|---|---|
| Складність впровадження | Низька | Висока |
| Стеля | Найбільший доступний сервер | Практично необмежена |
| Доступність | SPOF (один сервер) | Висока (відмова одного вузла — не зупинка системи) |
| Вартість на 10× користувачів | Не лінійна, висока | Ближча до лінійної |
| Регуляторні особливості | Простіше для експертизи | Потребує опису у моделі загроз |
Практичний підхід: вертикально до межі економічної доцільності, потім горизонтально. Межа: коли наступний крок «більше заліза» коштує більше за нову ноду кластера.
За досвідом — 5 000–10 000 активних користувачів (concurrent, не зареєстрованих). Симптоми:
Останній пункт часто стає вирішальним: системи, де простой неприйнятний (зміна) — переходять у кластер раніше за критеріями продуктивності.
Базова схема: load balancer → N стейтлес UBD-серверів → спільна БД. Спільна БД — окремий вузол масштабування, який розглядається пізніше.
HAProxy або Nginx. Алгоритм балансування — round-robin або least-connections. Sticky sessions не потрібні при правильній stateless архітектурі (див. нижче). Якщо sticky потрібні — це симптом проблеми, не рішення.
Health checks: load balancer регулярно перевіряє /health endpoint кожного UBD-сервера. Невідповідь >3 рази підряд → сервер видаляється з ротації.
UBD-сервери у кластері повинні бути stateless: ніякий локальний стан не зберігається між запитами. Сесія користувача — у Redis або у БД, не у пам’яті сервера. Файли, що завантажуються — у спільному файловому сховищі, не локально.
Це означає: будь-який запит будь-якого користувача може бути обслужений будь-яким сервером кластера. Якщо сервер падає, наступний запит маршрутизується на інший доступний вузол; у штатних сценаріях користувач не проходить повторний вхід.
На рівні >50k активних користувачів спільна БД стає вузьким місцем. Опції:
Перший крок: відокремлення читання від запису. Master приймає запис, кілька reader replica — читання. UBD конфігурується з read-write і read-only connection pools. Звичайні запити йдуть до replica, write-операції — до master.
Складність: read replicas мають невелику затримку (lag) реплікації — 0.1-2 секунди. Користувач, що щойно щось створив, може не одразу побачити це у списку. Рішення: для запитів одразу після write — насильно з master (через context flag).
Для multi-tenant систем. Tenant’и розподіляються між кількома незалежними БД. tenant_id → шард. UBD-сервер визначає шард з контексту користувача і робить запит до відповідної БД.
Переваги: краще масштабування БД за рахунок рознесення tenant’ів. Недоліки: складніша аналітика «по всіх tenant’ах».
Активні дані (поточний рік) — у швидкій БД. Архівні (старіше 1 року) — у повільнішому, але дешевшому сховищі. UBD маршрутизує запити прозоро.
Для держустанов з територіальними підрозділами в різних областях України — окрема архітектурна задача. Користувач у Львові не повинен чекати запиту до сервера у Києві.
Опції:
Останній варіант — для систем з 50k+ користувачів у кількох регіонах. Складний у налаштуванні, але дає підсекундну latency у кожному регіоні.
Кластер без моніторингу — гірше за один сервер: ви не знаєте, який саме сервер має проблеми. Обов’язкові метрики на кожний UBD-сервер:
На рівні кластера: розподіл навантаження між серверами (нерівномірність >30% — симптом проблеми у балансері), час відновлення після відмови вузла.
UBD спроєктований як stateless кластер з самого початку. Один вузол реалістично обслуговує 5–10 тис. активних користувачів залежно від профілю дій. Масштаб 50 000+ досягається кластером із додаванням вузлів, окремим масштабуванням СУБД і файлового сховища. Сесії зберігаються у спільному сховищі, rolling restart підтримується штатно з мінімізацією розривів сесій.