Базы данных

System Design: Twitter/X

В 2013 году Beyonce анонсировала беременность на Super Bowl. Twitter рухнул: 5 миллионов подписчиков одновременно открыли ленту, серверы не справились. После этого инцидента Twitter перепроектировал fan-out архитектуру с celebrity exception. Сегодня Maск с 150M подписчиков может публиковать без проблем.

  • **Twitter**: Fanout Service + Redis timeline cache для 300M пользователей
  • **Instagram**: аналогичная hybrid architecture для Stories и Feed
  • **WeChat Moments**: fan-out в пределах friend network (max 5000 friends) = нет celebrity problem

Требования и масштаб

Twitter (X) масштаб: 300 миллионов активных пользователей, 500 миллионов твитов в день, 300,000 QPS на чтение timeline. Функциональные требования: публикация твита, подписки, timeline (лента подписок), поиск. Нефункциональные: timeline за <200ms, consistency eventual (не критична).

Ключевое insight: чтений в 100x больше чем записей. Единственный способ обслуживать 300K timeline QPS - предвычислить timeline и кешировать. Вопрос: когда вычислять - при публикации (fan-out write) или при чтении (fan-out read)?

Twitter: 300K RPS на чтение timeline. Без предвычисления каждый запрос требует JOIN 20+ таблиц. Что произойдёт?

Fan-out on Write vs Fan-out on Read

Fan-out on Write: при публикации твита сразу добавить его в timeline кеш всех подписчиков. Чтение мгновенное. Проблема: celebrity с 100M подписчиков -> 100M write операций при каждом твите. Fan-out on Read: при запросе timeline найти все твиты подписок. Проблема: дорогое чтение.

Twitter изначально использовал Fan-out on Read. При росте нагрузки перешли на Fan-out on Write для обычных пользователей. Знаменитости (celebrities) - исключение: их твиты доставляются через Fan-out on Read чтобы избежать записи в 100M timeline.

Пользователь подписан на Илона Маска (150M подписчиков). Маск публикует твит. Сколько Redis операций выполнит Fan-out on Write?

Timeline Cache архитектура

Twitter использует Redis для хранения precomputed timelines. Каждый пользователь - Redis List с tweet_ids (не полными твитами). Преимущества: компактно, быстро, LPUSH/LRANGE O(1) или O(N). Полные данные твита получаются отдельным запросом (batch lookup).

Аль-Рамз (Fanout service) Twitter: отдельный сервис для fan-out операций. При публикации твита: Fanout service получает событие из Kafka, читает список подписчиков из социального графа, вставляет tweet_id в Redis timeline каждого подписчика. Decoupled от API layer.

Пользователь открывает Twitter после 3 дней отсутствия. Cache timeline мог устареть. Что произойдёт?

Hot Users проблема

Hot Users - аккаунты с миллионами подписчиков (celebrities). Fan-out on Write для них создаёт write storms. Twitter классифицирует пользователей: regular (Fan-out on Write), hot/celebrity (Fan-out on Read при чтении timeline).

Thundering Herd для hot users: Selena Gomez публикует сторис - 400M подписчиков одновременно загружают обновление. Instagram решает через CDN pre-warming: контент заранее распределяется по edge серверам до публикации (для запланированного контента).

Архитектура: 99% пользователей - fan-out on write, 1% celebrities - fan-out on read. Как определить threshold для celebrity?

Hybrid Design: финальная архитектура

Финальная архитектура Twitter: Hybrid fan-out. Regular users: fan-out on write -> Redis timeline cache. Celebrities: fan-out on read при загрузке timeline. Write path через Fanout Service (async via Kafka). Read path: Redis + Tweet Store + User Service.

Твит содержит только tweet_id в Redis timeline. Полные данные твита - в отдельном Tweet Store (может быть Redis Hash или specialised object store). Разделение позволяет обновлять данные твита (новые like counts) без пересоздания timelines.

Twitter хранит все твиты в одной PostgreSQL таблице

Twitter использует полиглот: PostgreSQL для метаданных, Kafka для event streaming, Redis для timeline cache, Cassandra для социального графа, S3 для медиа, Elasticsearch для поиска. Каждый компонент - специализированное решение.

Одна БД не масштабируется до 500M tweets/day. Polyglot persistence - не luxury, а необходимость при масштабе Twitter.

Пользователь удалил твит. В timeline кеше 5 млн подписчиков ещё есть tweet_id. Что сделать?

Итоги

  • **Fan-out on Write**: быстрое чтение, дорогая запись; не масштабируется для celebrities
  • **Hybrid**: regular users = fan-out write; celebrities = fan-out read; merge при чтении timeline
  • **Timeline кеш**: Redis List с tweet_ids (не полными данными); rebuild при miss из БД

Связанные темы

Twitter design использует несколько key concepts:

  • Redis — Redis Lists для timeline cache; core infrastructure Twitter feed
  • Кеширование — Fan-out on Write = precomputed cache strategy
  • Polyglot Persistence — Twitter = PostgreSQL + Redis + Cassandra + S3 + Elasticsearch

Вопросы для размышления

  • Как бы ты реализовал "Trending Topics" на Twitter? Какие структуры данных и как часто обновлять?
  • Пользователь отписывается от celebrity. Нужно ли чистить celebrity tweets из Redis timeline?
  • При шардировании Tweet Store по tweet_id - как эффективно получать последние твиты списка пользователей?

Связанные уроки

  • sd-14-twitter
System Design: Twitter/X

0

1

Войти