Требования: публикация постов, лента из постов подписок в обратном хронологическом порядке (или ранжированная), бесконечная прокрутка, лента открывается быстро (< 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, счётчики лайков — отдельный сервис (агрегирование), уведомления — отдельный конвейер.