Урок по треку System design 8 мин

Разборы типовых систем

Типовые задачи: сокращатель ссылок, лента, чат, rate limiter, уведомления, поиск подсказок.

На собесе дают одну из типовых задач. Её не нужно «знать наизусть», но полезно увидеть, как каждая раскладывается по одним и тем же шагам. Ниже ключевые идеи шести классических задач.

Сокращатель ссылок

  • Запись ~40 RPS, чтение ~4 000 RPS (100:1).
  • Код ссылки: 7 символов base62 дают 62^7 ≈ 3,5 трлн вариантов. Генерация из счётчика (выдача диапазонов id сервисам) или случайно с проверкой уникальности.
  • Хранилище: таблица code → url, точечный доступ по ключу, хорошо шардируется по коду.
  • Чтение через кеш (Redis), редирект 302 если нужна статистика переходов (301 закешируется браузером).
  • Аналитика переходов асинхронно через очередь в ClickHouse.

Лента новостей

  • Главный выбор: fan-out on write (при публикации раскладываем пост в ленты подписчиков, чтение быстрое) или fan-out on read (собираем ленту при чтении). У звёзд с миллионами подписчиков fan-out on write слишком дорог, поэтому гибрид: обычным раскладываем, посты звёзд подмешиваем при чтении.
  • Лента хранится как список id постов в Redis, сами посты в отдельном хранилище и кеше.
  • Пагинация курсором, а не offset.

Мессенджер

  • Постоянное соединение (WebSocket), отдельный слой gateway-серверов держит соединения; сервис присутствия знает, на каком gateway пользователь.
  • Сообщения сохраняются до доставки, у каждого сообщения id, монотонный внутри чата.
  • История шардируется по chat_id.
  • Доставка: сервер подтверждает приём, клиент подтверждает получение; офлайн-пользователю push.
  • Масштаб: один gateway держит десятки и сотни тысяч соединений.

Rate limiter

  • Где: на API-шлюзе или в общем Redis.
  • Алгоритм: token bucket или sliding window counter. В Redis атомарно через Lua-скрипт или INCR с TTL.
  • Ответ 429 с Retry-After. Решить, что делать при недоступности Redis: пропускать (fail open) или блокировать.

Сервис уведомлений

  • Принимает событие, по настройкам пользователя выбирает каналы (push, email, SMS), кладёт задачи в очереди по каналам.
  • Провайдеры внешние и медленные: ретраи, DLQ, rate limit под лимиты провайдера.
  • Дедупликация по ключу события, шаблоны, тихие часы.

Подсказки поиска (typeahead)

  • Жёсткая задержка: ответ < 100 мс, запрос на каждый символ, RPS высокий.
  • Префиксное дерево (trie) с топ-K запросами на каждом узле, построенное офлайн из логов поиска и обновляемое периодически.
  • Отдача из памяти, кеш на CDN и клиенте для популярных префиксов, debounce на клиенте.

Общая схема ответа

Для любой задачи: требования → оценка нагрузки → API → данные → схема → узкие места. Если не знаете конкретную технологию, опишите свойства, которые нужны («хранилище с быстрым доступом по ключу и TTL»), это засчитывается.

Что спросят на собесе

  • Спроектируйте сокращатель ссылок, ленту, чат или rate limiter.
  • Как генерировать уникальные короткие коды без коллизий.
  • Fan-out on write или on read и почему.
  • Как доставить сообщение пользователю, который был офлайн.
  • Как уложиться в 100 мс для подсказок поиска.

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.