← Назад к списку
Системный дизайнАрхитектура и алгоритмыMiddle

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

Короткий ответ

  • Два подхода: fan-out on write и fan-out on read
  • Push: при публикации пост раскладывается в ленты подписчиков
  • Pull: лента собирается из постов подписок при запросе
  • Гибрид: у знаменитостей pull, у обычных push
  • Ленты храним в Redis как списки идентификаторов постов
  • Тела постов и профили подтягиваем отдельным сервисом
  • Пагинация курсором, а не offset

Рабочее решение — гибридный fan-out: push для обычных авторов, pull для миллионников, ленты в Redis, тела постов отдельно.

Как сказать вслух

пример ответа

Я бы начал с выбора между push- и pull-моделью и сразу назвал проблему знаменитостей: раскладывать пост миллионам подписчиков дорого. Поэтому предложу гибрид. Ленту храню как список id в Redis, а содержимое постов достаю батчем по этим id.

Подробный ответ

Основной ответ

Ключевое решение — стратегия fan-out. Fan-out on write: при публикации воркер через очередь добавляет id поста в закэшированные ленты всех подписчиков; чтение дешёвое, запись дорогая. Fan-out on read: лента собирается в момент запроса слиянием последних постов подписок; запись дешёвая, чтение дорогое. Для авторов с миллионами подписчиков push создаёт лавину записей, поэтому их посты подмешиваются на чтении — получается гибрид. Лента в Redis хранит только id постов (например, sorted set по времени), тела постов, лайки и авторов добирает отдельный сервис батч-запросом. Ранжирование накладывается поверх уже собранного списка кандидатов.

Ключевые моменты

  • Проблема знаменитости. Push-модель для автора с 10 млн подписчиков означает 10 млн записей на один пост — таких авторов обслуживают pull-веткой.
  • Лента как список id. В кэше лежат только идентификаторы; денормализация тел постов в каждую ленту раздула бы память и усложнила редактирование.
  • Очередь на записи. Fan-out выполняется асинхронно воркерами: публикация подтверждается сразу, ленты доезжают с небольшой задержкой — это приемлемая eventual consistency.
  • Курсорная пагинация. Курсор по времени или id стабилен при вставке новых постов, offset при живой ленте дублирует и теряет элементы.

Практический контекст

Интервьюер проверяет, знаете ли вы компромисс push/pull и догадаетесь ли про гибрид без подсказки. Стоит уточнить: какой размер ленты хранить (обычно сотни последних id), нужна ли хронология или ранжирование, что показывать новому пользователю (fallback на популярное). Полезно проговорить инвалидацию при удалении поста и поведение при недоступности кэша.

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

  • Выбирают чистый push или чистый pull и не замечают проблему авторов-миллионников
  • Кладут в ленту целые посты вместо идентификаторов и получают дублирование данных
  • Предлагают SQL-join по подпискам на каждый запрос ленты при десятках миллионов пользователей

ИП Кочкин Алексей Сергеевич · ИНН 390509026279 · ОГРНИП 325390000030973 · jiniys2005@yandex.ru