Проверяет умение проектировать высоконагруженные системы с учётом реального времени и минимизации нагрузки.
Система должна:
Принимать просмотры через WebSocket для минимизации запросов.
Хранить счетчики в Redis для быстрого обновления.
Асинхронно сохранять данные в Postgres для аналитики.
Отдавать ленту видео через HTTP с предзагруженными счетчиками.
Архитектура системы:
Приём просмотров:
Клиент открывает WebSocket-соединение при старте приложения.
При просмотре видео отправляет событие: {"video_id": "abc", "user_id": "xyz"}.
Почему WebSocket? 1 соединение на сессию vs. HTTP-запрос на каждое видео.
Обработка событий:
WebSocket-сервер (на Python/Node.js) принимает события.
Увеличивает счетчик в Redis:
INCR video:abc:viewsПочему Redis? Операции в памяти за O(1), поддержка 100k+ RPS.
Синхронизация с БД:
Отдельный воркер раз в минуту переносит данные из Redis в Postgres:
UPDATE videos SET views = views + 100 WHERE id = 'abc';Получение ленты видео:
Клиент запрашивает ленту через HTTP: GET /feed?limit=15.
Backend:
Достаёт 15 видео из Postgres.
За один запрос получает счетчики из Redis:
MGET video:abc:views video:def:views ...Оптимизации:
Кэширование счетчиков: Для видео в ленте — всегда Redis.
Батчинг: WebSocket-сервер накапливает события (например, 100 мс) и отправляет пачкой.
Шардирование Redis: При огромной нагрузке данные распределяются по кластеру.
Вывод:
Сочетание Redis (реал-тайм) + Postgres (постоянное хранение) + WebSocket (минимум запросов) решает задачу.