Как принимать и сохранять просмотры видео
Что проверяют
Это задача на системный дизайн: умеете ли вы превратить поток мелких событий в надёжные счётчики и не положить базу. Интервьюер ждёт, что вы начнёте с требований, а не с таблицы. Следом обычно спрашивают, что будет при миллионе событий в минуту и как не посчитать один просмотр дважды.
Как отвечать
Сначала договоритесь, что считается просмотром: открытие плеера, досмотр до N секунд или процент ролика. Потом разведите приём и хранение:
- приём: лёгкий эндпоинт на FastAPI, который валидирует событие (
video_id, пользователь или сессия, время, позиция) и сразу отдаёт202 Accepted. В базу он не пишет; - буфер: очередь, чаще Kafka, иногда Redis Streams. Она сглаживает пики и позволяет перечитать события после сбоя;
- агрегация: консьюмер копит пачку и раз в несколько секунд делает один
INSERT ... ON CONFLICT DO UPDATE SET views = views + excluded.viewsвместо тысячи апдейтов; - сырые события: колоночная база вроде ClickHouse, где агрегаты по часам и регионам по миллиардам строк считаются быстро. В PostgreSQL остаётся итоговый счётчик для карточки видео;
- дедупликация: ключ из пользователя, видео и окна времени, например
SET ... NX EX 1800в Redis.
Проговорите гарантии: очередь даёт at-least-once, поэтому обработка должна быть идемпотентной. Счётчик на странице может отставать на секунды, это нормальная цена.
Где спотыкаются
Пишут UPDATE videos SET views = views + 1 на каждый просмотр. На популярном ролике все запросы бьются в одну строку, блокировки выстраиваются в очередь, и база встаёт.
Не думают о повторах и накрутке: обновление страницы, повторная отправка после сетевой ошибки, боты. Без дедупликации цифра ничего не значит.
Держат сырые события в той же PostgreSQL, что и продуктовые данные. Таблица вырастает до сотен миллионов строк, аналитика мешает основным запросам, а партиционирование и очистку никто не продумал.