System Design
Load balancers, caches, queues и регионы: соберите систему, которая выдержит нагрузку
- Single server. Всё на одной машине — Запрос и ответ, RPS, задержка (latency), предел мощности, когда server всего один, и single point of failure.
- Separate database. Данные на своей машине — Почему server без состояния (stateless) проще масштабировать и куда вынести данные.
- Load balancer. Нагрузка делится поровну — Горизонтальное масштабирование (horizontal scaling): load balancer как единый вход в систему, health check и правило N+1.
- Cache. Быстрые ответы из памяти — Cache-aside, hit rate и TTL: как снять нагрузку с database.
- CDN. Статика ближе к пользователю — Статика и динамика, edge locations и заголовки кеширования: как отдавать картинки и скрипты ближе к пользователю.
- Read replicas. Копии database для чтения — Read replicas, replication lag, failover и почему вся запись по-прежнему идёт в primary.
- Queue. Тяжёлая работа уходит в фон — Как вынести медленную работу из запроса: queue, workers, рост queue, пики и доставка at-least-once.
- Rate limiter. Защита от перегрузки — Rate limiter перед load balancer: быстрый ответ 429 вместо перегрузки, лимиты на клиента, backpressure и retries без лавины.
- Sharding. Данные по частям — Как разделить данные между независимыми databases: shard key, hot shards, запросы через все shards и resharding.
- Failover. Система переживает поломку — SPOF, единые точки отказа: второй load balancer, read replica, которая заменяет database, health check, failover и разница между availability и durability.
- Multi-region и CAP. Когда отключается целый регион — Второй регион для далёких пользователей и на случай потери дата-центра, асинхронная репликация и выбор между consistency и availability.
- Search index и event bus. Поиск и события — Event bus доставляет каждое изменение в search index и в аналитику: publish/subscribe, lag subscriber и eventual consistency.
- URL shortener. Итоговый проект — Спроектируйте систему с нуля: требования, оценки, API, а затем схема, которая держит пик, переживает отказы и укладывается в бюджет.
- Public API. Лимиты и квоты — API для разработчиков с тарифами Free и Pro: ядро с запасом под бюджет, а когда ключ Free начинает выкачивать базу — решить, кого ограничить, а за кого заплатить.
- Flash sale. Билеты на концерт — Билеты на концерт расходятся за минуты: waiting room впускает столько фанатов, сколько выдержит hot row, условный UPDATE и бронь с TTL не дают продать лишнего, а вторая дата получает свою строку и свою очередь.
- Notification system. Коды и рассылки — Уведомления магазина: коды OTP и рекламные рассылки идут разными путями (bulkhead), поэтому Black Friday не задерживает вход в аккаунт, а запасной провайдер спасает коды при аварии.
- Logging pipeline. Buffer и sampling — Сбор логов 3000 сервисов: buffer, чтобы agents не теряли данные, когда индекс не успевает, и sampling, когда шторм длиннее буфера.
- News feed. Fan-out on write и гибрид — Лента соцсети на 5 млн DAU: готовые timelines в cache, fan-out через queue, а когда приходят celebrities — гибрид, на котором ещё и экономим.
- Chat. Мессенджер для команд — Чат для команд в Европе и США: доставка событий через gateways, сервис в двух регионах с одним write leader, порядок сообщений и что теряется при потере региона.
- Video. Загрузка и просмотр — Видеоплатформа для онлайн-курсов: байты мимо servers — загрузка по presigned URL в object storage, просмотр через CDN, — а перекодирование в фоне, где workers держат под обычный вечер, а не под пик.
- File sync. Файлы на всех устройствах — Синхронизация файлов для команд: metadata отдельно от содержимого, куски в object storage, изменения через event bus по схеме notify-then-pull, а после сбоя — возвращение клиентов без каскада.
- Ride matching. Такси в двух регионах — Сервис такси в Европе и США: координаты водителей мимо database, свой поток в каждом регионе (geo-partitioning), а в новогоднюю ночь — деление Европы на cells.
- Payments. Платёжный шлюз — Шлюз платежей для магазинов: никогда не списать дважды (idempotency key), не потерять подтверждённый платёж (RPO = 0, transactional outbox) и пережить потерю региона.