План масштабирования dix.su¶
Составлен 2026-07-09 на основе анализа текущей архитектуры (см. CAPACITY.md). Реализация каждого следующего тира — по достижении порогов нагрузки предыдущего.
Архитектурный сплит: два типа нагрузки¶
У платформы два принципиально разных типа нагрузки с разной стратегией масштабирования:
WebSocket-туннели (dixu_proxy) — stateful, long-lived соединения.
Каждый device_client держит постоянное WSS-соединение. DeviceRegistry — in-memory ETS
на конкретной ноде. При горизонтальном масштабировании нужна межнодовая маршрутизация
(Phoenix.Tracker + libcluster), иначе запрос от браузера на ноде B не найдёт устройство
на ноде A. Это нетривиальное изменение кода — выполняется на Tier 3.
Веб-трафик (modulauth) — stateless, сессии в Redis. Масштабируется горизонтально тривиально: nginx балансирует на N инстансов, Redis общий.
Вывод: до Tier 3 — вертикальный апгрейд (проще, дешевле, ноль кода). С Tier 3 — горизонталь, но с разным подходом для каждого компонента.
Линейка тиров¶
Tier 0 — Текущее состояние¶
| Параметр | Значение |
|---|---|
| Сервер | 1 vCPU AMD, 1.9 GB RAM, 30 GB SSD, Debian 12 |
| Потолок устройств | ~300 device_client одновременно |
| Потолок пользователей | ~200 браузерных сессий одновременно |
| Активных relay | ~50–150 HTTP-запросов |
| TCP-соединений | ~500–1000 |
| Стоимость | ~$10–15/мес |
Узкие места: 1 CPU (1 BEAM-планировщик), RAM 1.9 GB, nginx 1 worker.
Порог перехода на Tier 1: load average стабильно > 0.7 или свободная RAM < 300 MB.
Tier 1 — Вертикальный апгрейд VPS (×10)¶
| Параметр | Значение |
|---|---|
| Сервер | 4 vCPU, 8 GB RAM — апгрейд того же VPS |
| Потолок устройств | ~3 000 device_client одновременно |
| Потолок пользователей | ~2 000 браузерных сессий одновременно |
| Стоимость | ~$40–60/мес |
Изменения в коде: ноль.
BEAM автоматически задействует все 4 ядра (schedulers_online = 4 — в 4× больше
пропускная способность relay). Spring WebFlux тоже масштабируется на все ядра.
Изменения в конфигурации:
# docker-compose.yml → postgres
command: postgres -c max_connections=300
# .env
DB_POOL_SIZE=20
JAVA_OPTS=-XX:+UseZGC -Xms512m -Xmx2g
# nginx dixu.conf.template
worker_connections 4096;
Добавить PgBouncer как промежуточный connection pooler перед Postgres.
Порог перехода на Tier 2: load average стабильно > 3.0 или RAM < 1 GB свободно.
Tier 2 — Выделенный сервер (×10)¶
| Параметр | Значение |
|---|---|
| Сервер | 16–32 vCPU, 64 GB RAM — выделенный сервер или облачный инстанс |
| Postgres | Отдельный сервер + read replica для аналитических запросов |
| Redis | Redis Sentinel (HA, 3 ноды) |
| Потолок устройств | ~30 000 device_client одновременно |
| Потолок пользователей | ~20 000 браузерных сессий одновременно |
| Стоимость | ~$200–500/мес |
Изменения в коде: ноль.
Изменения в конфигурации:
- nginx: worker_processes 16; worker_connections 8192;
- Postgres вынесен на отдельный хост, max_connections=500
- Read replica для аналитики (AnalyticsController → replica endpoint)
- Redis Sentinel для HA сессий
Партиционирование таблиц аналитики (tunnel_path_visits_daily,
tunnel_geo_visits_daily, tunnel_traffic_daily) по дате — к этому моменту
таблицы могут вырасти до миллионов строк.
Порог перехода на Tier 3: потребность в >30k одновременных устройств или нужна отказоустойчивость (single point of failure неприемлем).
Tier 3 — Горизонтальный кластер (×10)¶
| Параметр | Значение |
|---|---|
| Конфигурация | 3–5 нод dixu_proxy + 3 modulauth + Postgres primary/replica + Redis Cluster + LB |
| Потолок устройств | ~300 000 device_client одновременно |
| Потолок пользователей | ~200 000 браузерных сессий одновременно |
| Стоимость | ~$2 000–5 000/мес |
Главное изменение кода — distributed DeviceRegistry:
# mix.exs — добавить libcluster
{:libcluster, "~> 3.3"},
{:phoenix_pubsub, "~> 2.1"} # уже есть
# lib/dixu_proxy/application.ex — кластеризация
{Cluster.Supervisor, [topology, [name: DixuProxy.ClusterSupervisor]]},
{Phoenix.Tracker, [name: DixuProxy.Tracker, pubsub_server: DixuProxy.PubSub, ...]},
# lib/dixu_proxy_web/channels/proxy_channel.ex
# вместо локального Registry.lookup — Phoenix.Tracker.list
Запрос на ноде B маршрутизируется на ноду A, где реально подключён device_client. Без этого изменения горизонталь для туннелей невозможна.
modulauth — тривиально: 3 инстанса за nginx upstream, Redis Cluster для сессий.
Порог перехода на Tier 4: потребность в мультирегиональности или >300k устройств.
Tier 4 — Облако / Kubernetes (×10)¶
| Параметр | Значение |
|---|---|
| Конфигурация | K8s / ECS, 10–30 dixu_proxy pods, 10 modulauth, RDS + read replicas, CloudFront/Cloudflare CDN, multi-AZ |
| Потолок устройств | ~3 млн device_client одновременно |
| Потолок пользователей | ~2 млн браузерных сессий одновременно |
| Стоимость | ~$15 000–50 000/мес |
Изменения в коде: - Kubernetes-операторы, HPA (Horizontal Pod Autoscaler) по числу WS-соединений - PostgreSQL партиционирование (Citus или per-table range partitioning) - CDN для всей статики modulauth (CSS/JS/изображения) - Event streaming (Kafka/Kinesis) для аналитики — замена прямых INSERT в dixu_proxy
Порог перехода на Tier 5: международная экспансия с требованиями data residency (GDPR EU, РФ 152-ФЗ) или >3 млн устройств.
Tier 5 — Гиперскейл (VK и выше) (×10+)¶
| Параметр | Значение |
|---|---|
| Конфигурация | Multi-region (RU + EU + US + Asia), global anycast LB, database sharding, Erlang geo-clusters |
| Потолок устройств | Десятки миллионов |
| Потолок пользователей | 50–100 млн DAU |
| Стоимость | $200 000+/мес |
Ключевые изменения: - Региональные BEAM-кластеры с репликацией метаданных между регионами - Database sharding (Citus PostgreSQL или per-region шарды с global routing) - GDPR-compliant data residency: EU-пользователи → EU-кластер, данные не уходят за регион - Выделенные инженерные команды: SRE, platform, data
Примечание: Erlang/BEAM — это то, на чём построен WhatsApp (2 млрд пользователей, ~50 инженеров). Архитектура dixsu изначально выбрана правильно — технических барьеров для этого масштаба нет. Барьер на Tier 5 — продуктовый и операционный, не технический.
Сводная таблица¶
| Tier | Устройств | Пользователей | Код | Стоимость |
|---|---|---|---|---|
| 0 (сейчас) | 300 | 200 | — | ~$15/мес |
| 1 | 3 000 | 2 000 | Ноль | ~$50/мес |
| 2 | 30 000 | 20 000 | Ноль | ~$300/мес |
| 3 | 300 000 | 200 000 | libcluster + Tracker | ~$3 000/мес |
| 4 | 3 000 000 | 2 000 000 | K8s, CDN, event streaming | ~$30 000/мес |
| 5 | 30 000 000+ | 50–100 млн DAU | Multi-region, sharding | $200 000+/мес |
Правило перехода¶
Переходить на следующий тир по факту достижения порога, а не заранее. Каждый преждевременный апгрейд — это переплата и операционная сложность без отдачи. Erlang/BEAM хорошо держит нагрузку до последнего — пороги видны по
load averageи свободной RAM, мониторить черезdocker statsили Prometheus.
Текущий сигнал для старта Tier 1: load average > 0.7 при нормальной работе сервиса.