---
title: Алекс Сюй, «System Design. Подготовка к сложному интервью» (Vol. 1, рус. изд.) — глава 11: Лента новостей
source: materials/System Design. Подготовка к сложному интервью.pdf, стр. 183–196
конспект: TASK-45.38, извлечено pymupdf 2026-09-17; ниже полный «грязный» текст главы + выжимка
статус: выжимка и перенос в knowledge-base.md / methodology.md / classic-designs.md — см. _map.md
---

# Глава 11. Лента новостей

## Выжимка

Два процесса: **публикация поста** и **составление ленты**. API: `POST /v1/me/feed` (content, auth_token), `GET /v1/me/feed`. 10 млн DAU, до 5000 друзей, лента — обратная хронология.

**Fan-out — сердце задачи.** Три модели:

- **При записи (push)**: пост сразу раскладывается в кэш лент друзей → чтение быстрое; минусы — «горячие клавиши» у знаменитостей (миллионы вставок) и пустая трата ресурсов на неактивных.
- **При чтении (pull)**: лента собирается на запрос → дёшево для неактивных и селебрити; чтение медленное.
- **Гибрид (выбор книги)**: push для обычных пользователей, pull для контента знаменитостей/гигантских подписчиков; consistent hashing выравнивает нагрузку fanout-узлов.

**Публикация**: web-серверы (аутентификация + rate limiting против спама) → сервис постов (БД + кэш постов) → сервис ветвления: графовая БД (друзья) → кэш пользователей (фильтры: mute, настройки приватности) → **очередь сообщений** → узлы ветвления → **кэш лент** (хранит только `<post_id, user_id>`, не контент!; ограниченный размер — дальше подгрузка из БД).

**Чтение**: сервис ленты → кэш ленты → кэш постов/БД; медиа из CDN. Плюс сервис уведомлений.

Перенос: classic-designs §2 (сверка), KB §8 (очереди), §14.6 (fan-out push/pull/гибрид).

## Полный текст (грязная выгрузка)

11 
ПРОЕКТИРОВАНИЕ ЛЕНТЫ НОВОСТЕЙ
В этой главе вам предлагается спроектировать ленту новостей. Согласно 
справке Facebook, «Лента новостей — это постоянно обновляемый список 
историй в центральной части вашей домашней страницы. Она включает об­
новления информации о состоянии, фотографии, видео, ссылки, активность 
приложений и лайки, приходящие от людей, страниц и групп, на которые 
вы подписаны в Facebook» [1]. Эта задача часто встречается на интервью. 
Другие ее разновидности могут заключаться в проектировании новостной 
ленты Facebook, ленты Instagram, потока сообщений Twitter и т. д.
Рис. 11.1


184      ГЛАВА 11 
ШАГ 1: ПОНЯТЬ ЗАДАЧУ И ОПРЕДЕЛИТЬ МАСШТАБ РЕШЕНИЯ
Когда вас просят спроектировать ленту новостей, начинать следует 
с уточняющих вопросов, которые помогут вам понять, что именно имеет 
в виду интервьюер. Вам как минимум нужно определиться со списком 
возможностей, которые должны поддерживаться. Вот пример диалога 
между кандидатом и интервьюером:
Кандидат: «Это приложение должно быть мобильным, браузерным 
или и тем и другим?»
Интервьюер: «И тем и другим».
Кандидат: «Какие его основные возможности?»
Интервьюер: «Пользователь может публиковать посты и просматри­
вать ленту новостей с постами его друзей».
Кандидат: «Лента новостей сортируется в обратном хронологическом 
порядке или по какому-то другому принципу? Например, статьи от 
близких друзей могут иметь повышенный приоритет».
Интервьюер: «Чтобы не усложнять, предположим, что лента сорти­
руется в обратном хронологическом порядке».
Кандидат: «Сколько друзей может быть у пользователя?»
Интервьюер: «5000».
Кандидат: «Какой объем трафика?»
Интервьюер: «10 миллионов DAU».
Кандидат: «Может ли лента в дополнение к тексту содержать изо­
бражения и видео?»
Интервьюер: «Да, она может содержать медиафайлы, включая изо­
бражения и видео».
Уточнив требования, мы можем переходить к проектированию системы.
ШАГ 2: ПРЕДЛОЖИТЬ ОБЩЕЕ РЕШЕНИЕ И ПОЛУЧИТЬ СОГЛАСИЕ
Архитектура состоит из двух процессов — публикации постов и форми­
рования новостной ленты.


Проектирование ленты новостей 
    185
 
 Публикация постов. Когда пользователь публикует пост, соответ­
ствующие данные записываются в кэш и в базу данных. Затем пост 
появляется в ленте новостей друзей пользователя.
 
 Составление новостной ленты. Чтобы не усложнять, предположим, 
что лента формируется путем агрегации постов друзей в обратном 
хронологическом порядке.
API ленты новостей
API ленты новостей — это основной механизм взаимодействия клиентов 
с серверами. API основаны на HTTP и позволяют клиентам выполнять 
такие действия, как публикация обновлений состояния, получение 
новостной ленты, добавление друзей и т. д. Мы обсудим два основных 
действия: публикацию постов и получение ленты.
API для публикации постов
Чтобы опубликовать пост, нужно отправить серверу HTTP-запрос типа 
POST. Пример:
POST /v1/me/feed
Параметры:
 
 content: текст поста;
 
 auth_token: используется для аутентификации API-запросов.
API для получения ленты
API для получения ленты новостей выглядит так:
GET /v1/me/feed
Параметры:
 
 auth_token: используется для аутентификации API-запросов.
Публикация статей
На рис. 11.2 показан общий принцип публикации ленты.


186      ГЛАВА 11 
Балансировщик 
нагрузки
v1/me/feed?
   content=Hello&
   auth_token={auth_token}
Сервис 
ветвления
Сервис постов
Сервис 
уведомлений
Веб-серверы
Кэш новост-
ной ленты
БД с постами
Кэш постов
Веб-браузер
Пользователь
Мобильное 
приложение
КЭШ
КЭШ
КЭШ
КЭШ
КЭШ
КЭШ
Рис. 11.2
 
 Пользователь может просматривать ленты новостей в браузере 
или в мобильном приложении. Чтобы опубликовать пост с текстом 
Hello, используется следующий API-вызов:
/v1/me/feed?content=Hello&auth_token={auth_token}
 
 Балансировщик нагрузки распределяет трафик между серверами.


Проектирование ленты новостей 
    187
 
 Веб-серверы перенаправляют трафик к разным внутренним сер­
висам.
 
 Сервис постов сохраняет статьи в базе данных и кэше.
 
 Сервис ветвления добавляет новый контент в новостные ленты 
друзей. Данные новостной ленты хранятся в кэше, чтобы их можно 
было быстро извлечь.
 
 Сервис уведомлений. Сообщает друзьям о появлении нового кон­
тента и рассылает push-уведомления.
Составление ленты новостей
В этом разделе мы обсудим внутренний процесс составления новостной 
ленты. В общих чертах он показан на рис. 11.3.
Балансировщик 
нагрузки
v1/me/feed
Сервис новостной 
ленты
Веб-серверы
Веб-браузер
Пользователь
Мобильное 
приложение
Кэш новостной 
ленты
КЭШ
КЭШ
КЭШ
Рис. 11.3


188      ГЛАВА 11 
 
 Пользователь отправляет запрос для получения своей ленты ново­
стей. Запрос имеет вид /v1/me/feed.
 
 Балансировщик нагрузки направляет трафик к веб-серверам.
 
 Веб-серверы направляют запросы к серверу новостной ленты.
 
 Сервис новостной ленты извлекает ленту новостей из кэша.
 
 Кэш новостной ленты хранит идентификаторы статей, необходи­
мые для составления ленты новостей.
ШАГ 3: ПОДРОБНОЕ ПРОЕКТИРОВАНИЕ
В предыдущем разделе вкратце описывалось два процесса: публикация 
постов и составление ленты новостей. Здесь мы подробнее обсудим их.
Подробно о публикации статей
На рис. 11.4 подробно изображен процесс публикации постов. Большин­
ство компонентов было рассмотрено при обсуждении общей архитекту­
ры. Здесь же мы сосредоточимся на двух из них: веб-серверах и сервисе 
ветвления.
Веб-серверы
Помимо взаимодействия с клиентами, веб-серверы отвечают за аутен­
тификацию и ограничение трафика. Публиковать посты разрешено 
только пользователям, которые предоставили при входе в систему 
действительное значение auth_token. Система ограничивает количество 
постов, которое можно публиковать за определенный промежуток вре­
мени. Это незаменимое средство борьбы со спамом и нежелательным 
контентом.
Сервис ветвления
Сервис ветвления доставляет посты всем вашим друзьям. Он может 
быть основан на двух моделях: ветвление при записи (пассивная модель) 
и ветвление при чтении (активная модель). Оба варианта имеют свои 
преимущества и недостатки. Давайте посмотрим, как они работают, и вы­
берем тот, который лучше всего походит для нашей системы.


Проектирование ленты новостей 
    189
Балансировщик нагрузки
Сервис 
ветвления
Сервис 
уведомлений
Веб-серверы
Аутентификация
получение ID друзей
получение данных друзей
Очередь сообщений
Сервис постов
БД с постами
Кэш новостной 
ленты
Узлы ветвления
Кэш постов
Кэш пользо-
вателей
БД пользо-
вателей
Графовая БД
1
2
5
4
3
КЭШ
КЭШ
КЭШ
КЭШ
КЭШ
КЭШ
Веб-браузер
Пользователь
Мобильное 
приложение
v1/me/feed?
   content=Hello&
   auth_token={auth_token}
Ограничение трафика
КЭШ
КЭШ
КЭШ
Рис. 11.4
Ветвление при записи. В рамках этого подхода лента новостей составля­
ется во время записи. После публикации новый пост сразу же помещается 
в кэш друзей.
Преимущества:
 
 новостная лента генерируется в реальном времени и сразу стано­
вится доступной для друзей;


190      ГЛАВА 11 
 
 получение новостной ленты происходит быстро, так как она со­
ставляется во время записи.
Недостатки:
 
 если у пользователя много друзей, получение их списка и генерация 
новостной ленты для каждого из них будет происходить медленно. 
Это называется проблемой горячих клавиш;
 
 если пользователь неактивен или редко входит в систему, состав­
ление его новостной ленты будет пустой тратой вычислительных 
ресурсов.
Ветвление при чтении. Лента новостей генерируется во время чтения. 
Последние посты загружаются, когда пользователь загружает домашнюю 
страницу.
Преимущества:
 
 ветвление при чтении лучше подходит для пользователей, которые 
не очень активны или редко входят в систему, так как при этом на 
них не тратятся лишние ресурсы;
 
 данные не заносятся в кэш каждого друга, поэтому при большом 
количестве друзей проблем не возникает.
Недостатки:
 
 загрузка новостной ленты происходит медленно, поскольку она не 
составляется заранее.
Мы применим гибридный поход, чтобы получить преимущества обеих 
моделей и избежать их недостатков. Нам крайне важно, чтобы ленту ново­
стей можно было получить быстро, поэтому для большинства пользовате­
лей преду­смотрена модель push. Контент знаменитостей и пользователей 
с большим количеством друзей/подписчиков можно запрашивать по 
требованию, чтобы не перегружать систему. Согласованное хеширова­
ние позволяет справляться с большим количеством друзей за счет более 
равномерного распределения запросов/данных.
Давайте подробно рассмотрим сервис ветвления, показанный на рис. 11.5.


Проектирование ленты новостей 
    191
Сервис ветвления
получение ID друзей
получение данных друзей
Очередь сообщений
Кэш новостной
 ленты
Узлы ветвления
Кэш пользо-
вателей
БД пользо-
вателей
Графовая БД
1
2
5
4
3
КЭШ
КЭШ
КЭШ
КЭШ
КЭШ
КЭШ
Рис. 11.5
Сервис ветвления работает следующим образом:
1.	 Извлекаем идентификаторы друзей из графовой базы данных. 
Графовая БД подходит для управления связями между друзьями 
и рекомендации новых друзей. Если хотите узнать больше, озна­
комьтесь со справочным материалом [2].
2.	 Получаем информацию о друзьях из кэша пользователей. Система 
фильтрует полученный список с учетом пользовательских настроек. 
Например, если вы решили «заглушить» одного из своих друзей, его 
посты не попадут в вашу ленту. Пост также может быть скрыт по той 
причине, что пользователь решил поделиться информацией лишь 
с определенным кругом друзей или скрыть его от других людей.
3.	 Отправляем список друзей и ID новой статьи в очередь сообщений.


192      ГЛАВА 11 
4.	 Узлы ветвления достают данные из очереди сообщений и сохраня­
ют содержимое ленты новостей в кэше. Кэш ленты новостей можно 
представить в виде хеш-таблицы <post_id, user_id>. Новые посты 
добавляются в нее в момент создания, как показано на рис. 11.6. 
Если хранить в кэше данные о пользователях и содержимое по­
стов, расход памяти сильно вырастет. Поэтому мы храним лишь 
идентификаторы. Чтобы ограничить расход памяти, мы устанав­
ливаем лимит, который можно настраивать. Вероятность того, что 
пользователь будет прокручивать тысячи постов, невысока. Боль­
шинство людей интересуются самым новым контентом, поэтому 
доля промахов кэша остается низкой.
5.	 Сохраняем <post_id, user_id> в кэш ленты новостей. На рис. 11.6 
показан пример того, как может выглядеть закэшированная но­
востная лента.
post_id
user_id
post_id
user_id
post_id
user_id
post_id
user_id
post_id
user_id
post_id
user_id
post_id
user_id
post_id
user_id
Рис. 11.6
Подробно о получении ленты новостей
На рис. 11.7 подробно проиллюстрирован процесс получения ленты 
новостей.
Как видно на рис. 11.7, медиаконтент (изображения, видео и т. д.) хранит­
ся в CDN, чтобы его можно было быстро извлекать. Давайте посмотрим, 
как клиент получает ленту новостей.
1.	 Пользователь отправляет запрос вида /v1/me/feed, чтобы полу­
чить свою ленту новостей.


Проектирование ленты новостей 
    193
Балансировщик 
нагрузки
/v1/me/feed
Сервис новостной
ленты
CDN
Веб-серверы
Аутентификация
Кэш новостной 
ленты
Кэш пользо-
вателей
БД пользо-
вателей
Кэш постов
 БД постов
1
3
4
5
5
2
6
КЭШ
КЭШ
КЭШ
КЭШ
КЭШ
КЭШ
КЭШ
КЭШ
КЭШ
Пользователь
Веб-браузер
Мобильное
приложение
Ограничение трафика
Рис. 11.7
2.	 Балансировщик нагрузки распределяет запросы между веб-
серверами.
3.	 Веб-серверы обращаются за новостной лентой к соответствующему 
сервису.
4.	 Сервис извлекает из кэша новостной ленты список с идентифика­
торами постов.
5.	 Лента новостей пользователя не ограничивается списком иден­
тификаторов. Она содержит имена пользователей, аватары, текст 


194      ГЛАВА 11 
постов, изображения и т. д. Таким образом, сервис новостной ленты 
извлекает полные данные о пользователях и постах из соответству­
ющих кэшей, чтобы составить полноценную автоматизированную 
ленту новостей.
6.	 Полноценная лента новостей возвращается на клиент в формате 
JSON для дальнейшего отображения.
Архитектура кэширования
Кэш имеет очень большое значение для системы новостных лент. Мы 
делим его на 5 слоев, как показано на рис. 11.8.
лента новостей
горячий кэш
обычный
подписчик
подписка
лайк
ответ
другое
счетчик лайков
счетчик ответов
другие счетчики
Лента новостей
Контент
Социальный 
граф
Счетчики
Действие
Рис. 11.8
 
 Лента новостей хранит идентификаторы постов.
 
 Контент хранит данные каждого поста. Популярный контент на­
ходится в горячем кэше.
 
 Социальный граф хранит данные об отношениях между пользо­
вателями.
 
 Действие хранит информацию о действиях пользователя по отно­
шению к посту: лайкнул, оставил ответ или что-то другое.


Проектирование ленты новостей 
    195
 
 Счетчики включают счетчики лайков, ответов, подписчиков, тех, 
на кого пользователь подписан, и т. д.
ШАГ 4: ПОДВЕДЕНИЕ ИТОГОВ
В этой главе мы спроектировали ленту новостей. Наша архитектура 
со­стоит из двух процессов: публикации постов и получения новостной 
ленты.
У задач, которые встречаются на интервью по проектированию ИТ-
систем, не бывает идеальных решений, и эта система не исключение. 
У каждой компании есть уникальные ограничения, которые необхо­
димо учитывать при проектировании. Вы должны понимать сильные 
и слабые стороны архитектурных и технологических аспектов системы. 
Если у вас еще остается несколько минут, можете затронуть вопросы 
масштабирования. Чтобы не повторяться, ниже перечислены только 
основные тезисы.
Масштабирование базы данных:
 
 вертикальное и горизонтальное масштабирование;
 
 SQL и NoSQL;
 
 репликация вида «ведущий–ведомый»;
 
 реплики для чтения;
 
 модели согласованности;
 
 шардинг базы данных.
Несколько советов:
 
 не храните состояние веб-уровня;
 
 кэшируйте данные как можно активнее;
 
 обеспечьте поддержку разных центров обработки данных;
 
 ослабьте связанность компонентов с помощью очередей сообщений;
 
 отслеживайте ключевые метрики, такие как QPS, в часы пик и ла­
тентность в момент, когда пользователи обновляют свои новостные 
ленты.


196      ГЛАВА 11 
Поздравляем, вы проделали длинный путь и можете гордиться собой. 
Отличная работа!
СПРАВОЧНЫЕ МАТЕРИАЛЫ
[1]  How News Feed Works: https://www.facebook.com/help/327131014036297/
[2]  Friend of Friend recommendations Neo4j and SQL Server: https://web.
archive.org/web/20210116003626/http://geekswithblogs.net/brendonpage/
archive/2015/10/26/friend-of-friend-recommendations-with-neo4j.aspx
