Ответ вслух Senior Разборы систем спрашивают часто обновлено

Спроектируйте ленту новостей

Вопрос

Спроектируйте ленту новостей соцсети: пользователь подписан на других и видит их посты, новые сверху.

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Требования: публикация, подписки, лента в обратном хронологическом порядке, загрузка быстрее 200 мс, пост может появиться у подписчиков через несколько секунд. Нагрузка: 100 млн DAU по 10 открытий это около 10 000 RPS чтения, в пике 30 000.

Что должно прозвучать в ответе

  • Требования: публикация поста, подписка, лента с пагинацией; порядок по времени (ранжирование вне рамок или упрощённо); лента грузится < 200 мс, допустима задержка появления поста в секунды

  • Оценка нагрузки: 100 млн DAU, 10 открытий ленты в день ≈ 10 000 RPS чтения, в пике ~30 000; 10 млн постов в сутки ≈ 100 RPS записи; при 200 подписчиках в среднем ≈ 20 000 вставок в ленты в секунду

  • API: POST /posts; GET /feed?cursor=...&limit=20; POST /users/{id}/follow

  • Данные: посты в шардированной БД по author_id, граф подписок отдельно, готовые ленты как списки id постов в Redis (последние ~500), медиа в S3

  • Компоненты: сервис постов, очередь событий публикации, fan-out воркеры, сервис ленты, кеш постов, CDN для медиа

  • Узкие места: аккаунты-звёзды (гибрид on write + on read), неактивные пользователи (не раскладывать, собирать при входе), пагинация курсором, память Redis, удаление и редактирование постов

Что могут спросить следом

  • Как поступить с автором на 30 млн подписчиков?
  • Как добавить ранжирование?
  • Что если Redis с лентами потерян?

Разбор

Требования: публикация, подписки, лента в обратном хронологическом порядке, загрузка быстрее 200 мс, пост может появиться у подписчиков через несколько секунд. Нагрузка: 100 млн DAU по 10 открытий это около 10 000 RPS чтения, в пике 30 000. Постов 10 млн в сутки, это 100 RPS записи, но при 200 подписчиках в среднем раскладка даёт около 20 000 вставок в ленты в секунду. API: публикация, лента с курсором, подписка. Данные: посты шардирую по author_id, подписки в отдельном хранилище, готовая лента пользователя это список последних 500 id постов в Redis: 100 млн × 500 × 8 байт около 400 ГБ, кластер Redis это выдержит. Компоненты: сервис постов пишет пост и событие в Kafka, fan-out воркеры раскладывают id по лентам подписчиков, сервис ленты берёт id из Redis и подтягивает посты из кеша. Узкое место звёзды: для авторов с миллионами подписчиков не раскладываю, а подмешиваю их свежие посты при чтении. Неактивным ленты не раскладываю, собираю при входе. Если Redis потерян, ленты восстанавливаются сборкой из постов подписок, это медленнее, но работает.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.