Получить доступ

Спроектируйте ленту новостей социальной сети.

SeniorЗадачи на проектирование
Ещё спрашивают так:
  • Fan-out on write или fan-out on read?
  • Как построить ленту подписок для миллионов пользователей?
Коротко

Главный выбор — когда собирать ленту. Fan-out on write: при публикации положить id поста в ленты всех подписчиков — чтение мгновенное. Fan-out on read: собирать при открытии из постов подписок — дорогое чтение. На практике гибрид: обычные авторы — на записи, знаменитости — на чтении.

  • Лента в кэше — список id постов (Redis sorted set по времени), посты — отдельно
  • Пагинация курсором, а не OFFSET
  • Ранжирование — отдельный этап поверх кандидатов

А ещё Неактивным пользователям ленту не раскладывать — собрать при входе

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Требования: публикация постов, лента из постов подписок в обратном хронологическом порядке (или ранжированная), бесконечная прокрутка, лента открывается быстро (< 200 мс). Оценка: 200 млн пользователей в день, каждый открывает ленту 10 раз — 2 млрд чтений в день (~25 000/с, пик ×3); публикаций 50 млн в день (~600/с); в среднем 200 подписчиков, у знаменитостей — десятки миллионов.

Модель данных: посты (post_id, author, created, content) — шардированное хранилище по post_id или автору; граф подписок (follower → followees, followee → followers); лента — список id.

Fan-out on write (push). При публикации воркер читает подписчиков автора и добавляет post_id в их ленты (Redis sorted set с score = время, обрезанный до 500–1000 элементов). Чтение — взять верх списка и подгрузить посты пачкой (из кэша постов). Плюсы — быстрое чтение. Минусы — пост знаменитости с 50 млн подписчиков = 50 млн записей, задержка доставки и шторм нагрузки; место на ленты неактивных пользователей.

Fan-out on read (pull). При открытии ленты взять подписки, последние посты каждой и слить (k-way merge кучей). Плюсы — запись дешёвая. Минусы — чтение дорогое при сотнях подписок и частых открытиях.

Гибрид — так делают крупные сети: посты обычных авторов раскладываются при записи; посты авторов с огромной аудиторией не раскладываются, а подмешиваются при чтении (их немного у каждого пользователя, и их последние посты горячо кэшируются). Ленты раскладываются только активным пользователям; вернувшемуся после долгого перерыва ленту строят при входе.

Чтение и пагинация: курсор — score последнего показанного элемента (ZREVRANGEBYSCORE ... < cursor LIMIT 20), а не OFFSET: новые посты не сдвигают страницы и не дают дублей. Посты — пачкой из кэша по id (multi-get).

Ранжирование: из ленты берутся кандидаты (сотни), модель ранжирования оценивает и сортирует; результат кэшируется на короткое время.

Остальное: удаление и редактирование поста (ленты хранят id — удалённый пост отфильтровывается при подгрузке), приватность (проверка при показе), медиа — в объектном хранилище и CDN, счётчики лайков — отдельный сервис (агрегирование), уведомления — отдельный конвейер.

Пример

Публикация (автор с 300 подписчиками):
  POST /posts → posts DB → событие в Kafka → fan-out воркер
  → для каждого активного подписчика: ZADD feed:{user} <ts> <post_id>; ZREMRANGEBYRANK feed:{user} 0 -1001
Публикация знаменитости (20 млн): только в posts + кэш «последние посты автора».
Чтение: ZREVRANGE feed:{me} + последние посты моих знаменитостей → слияние → MGET post:{id}... → ранжирование.

Что хотят услышать

  • Оценка нагрузки и асимметрия чтения и записи.
  • Fan-out on write и on read, их плюсы и минусы.
  • Гибрид для знаменитостей и неактивных пользователей.
  • Хранение ленты как списка id, пагинация курсором, ранжирование.

Частые ошибки

  • Делать JOIN подписок и постов в реляционной базе на каждое открытие ленты.
  • Раскладывать посты знаменитостей всем подписчикам синхронно.

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем