← все задачи

Задача 9 из 10

Аналитика в реальном времени

Спроектируйте подсчёт статистики просмотров в реальном времени: сколько уникальных пользователей посмотрели материал и какие материалы в топе за последний час.

Уровень: Продвинутый На собеседовании: 45–60 минут потоковая обработкаприблизительные структурыопоздавшие события

Функциональные требования

  • Счётчик просмотров по материалу
  • Уникальные пользователи за период
  • Топ-10 популярного за час и за сутки
  • Дашборд, который обновляется почти в реальном времени

Нефункциональные требования

  • 100 000 событий в секунду
  • Цифры обновляются с задержкой до 30 секунд
  • Погрешность в уникальных до 1% допустима
  • События приходят с опозданием и дублями
  • История хранится год

Нарисуйте архитектуру

Не гонитесь за красотой: на собеседовании от схемы нужно, чтобы по ней было видно путь запроса и где лежат данные. Сначала нарисуйте сами — эталон и разбор ниже.

Блок из палитры — добавить. Тащите мышкой или пальцем. Двойной клик по названию — переименовать. «Связь» — щёлкнуть по одному блоку, потом по другому: получится стрелка.

Схема сохраняется в этом браузере — вкладку можно закрыть и вернуться позже.

1 С чего начать, если ступор
  • Посчитайте, сколько памяти нужно на точные уникальные — этот расчёт сам подскажет решение.
  • Приблизительные структуры: HyperLogLog для уникальных, Count-Min Sketch для топа.
  • Разделите горячий слой (последние минуты) и холодный (история за год).
  • События опаздывают: окно агрегации должно уметь принимать прошлое.
  • At-least-once из очереди означает, что счётчик может задвоиться — решите, важно ли это здесь.
2 Эталонная схема

Один поток событий и два независимых потребителя: стрим-агрегатор держит последние минуты в Redis, батч складывает часовые агрегаты в историю. Уникальных считаем приблизительно — точность здесь стоит дороже, чем стоит сама цифра.

Это один из рабочих вариантов, а не единственно верный. Если у вас иначе, но вы можете объяснить почему — на собеседовании это ровно то, что нужно.

3 Разбор: что должно прозвучать

Оценка объёма

  • Точный подсчёт уникальных требует хранить идентификаторы: миллионы пользователей на каждый материал
  • HyperLogLog даёт ~1% погрешности примерно на 12 КБ на счётчик — разница на порядки
  • Требование «погрешность до 1% допустима» дано в задаче не случайно: на него надо сослаться

Приблизительные структуры

  • HyperLogLog для уникальных, объединяется по периодам без пересчёта
  • Count-Min Sketch для топа: память фиксирована, ошибка только в сторону завышения
  • Точные счётчики просмотров при этом никто не отменял — они дешёвые

Горячий и холодный слой

  • Горячий слой: последние минуты в памяти, быстрый и недолговечный
  • Холодный: часовые и суточные агрегаты в аналитическом хранилище
  • Дашборд склеивает оба — и это надо явно проговорить, иначе непонятно, откуда цифры

Опоздавшие события

  • Событие с мобильного может прийти через час после самого просмотра
  • Окно с watermark: до какого момента мы ещё принимаем прошлое, после — отбрасываем или досчитываем
  • Время события и время обработки — разные вещи, и путать их нельзя

Дубли

  • At-least-once означает, что одно событие обработается дважды
  • Дедупликация по идентификатору события в окне или идемпотентные операции
  • Для счётчика просмотров дубль на уровне 0.1% часто дешевле, чем дедупликация — но это осознанное решение

Куда копать дальше, если спросят

  • Шардирование по ключу материала и горячие материалы, которые не влезают в один шард
  • Ретеншен: год истории — это сколько и в каком формате
  • Пересчёт задним числом, когда нашли ошибку в агрегации
  • Чем отличается lambda-архитектура от kappa и зачем тут два потребителя

Следующая задача: Планировщик отложенных задач

Пять инстансов смотрят в одну таблицу задач. Самая распределённая задача набора: координация, аренда и отсутствие exactly-once.