Обновлено: 25 марта 2026 г. в 04:52

URL Shortener (TinyURL)

medium

Классическая задача: base62 encoding, ID generation (Snowflake), caching strategy и 301 vs 302 redirect.

У сокращателя ссылок внешне простой интерфейс, но внутри это задача про экстремально горячий путь чтения, генерацию коротких идентификаторов и дешевые redirects at scale.

Кейс полезен тем, что заставляет отдельно думать о write path создания short code и read path редиректа: cache hit ratio, storage lookups, hot keys и отказоустойчивость edge-сервинга.

В интервью и архитектурных обсуждениях он хорош тем, что быстро показывает, умеете ли вы видеть асимметрию чтений и записей, выделять настоящий bottleneck и не усложнять решение раньше времени.

Control Plane

Фокус на governance-политиках, лимитах, маршрутизации и стабильности edge-поведения.

Data Path

Нужно держать предсказуемую latency и throughput при росте трафика и burst-нагрузке.

Failure Modes

Покрывайте fail-open/fail-close, деградацию и безопасный fallback при частичных отказах.

Ops Ready

Показывайте мониторинг saturation, retry storm и operational guardrails.

URL Shortener (TinyURL, bit.ly) — классическая задача на System Design интервью. Она идеально подходит для начинающих, так как сочетает простоту концепции с интересными архитектурными решениями: генерация уникальных ID, масштабирование базы данных и обработка высокой нагрузки на чтение.

Глава 8

Alex Xu: URL Shortener

Детальный разбор в книге System Design Interview

Читать обзор

Зачем нужен URL Shortener

Удобство

Короткие ссылки легче запомнить, поделиться в соцсетях и использовать в SMS

Аналитика

Отслеживание кликов, географии пользователей и источников трафика

Контроль

Возможность отключить ссылку, установить срок действия или пароль

Требования

Функциональные

  • FR1
    Создание короткой ссылки из длинного URL
  • FR2
    Редирект по короткой ссылке на оригинальный URL
  • FR3
    Опциональный TTL (время жизни ссылки)
  • FR4
    Custom alias (опционально)

Нефункциональные

  • NFR1
    100M новых URL в день (write)
  • NFR2
    10:1 read/write ratio → 1B redirects/day
  • NFR3
    Latency < 100ms для редиректа
  • NFR4
    99.9% availability

Back of the Envelope

Traffic

  • Write: 100M/day = 1,160 QPS
  • Read: 1B/day = 11,600 QPS
  • Peak: ~23,000 QPS (2x average)

Storage

  • Avg URL size: 500 bytes
  • 100M × 500B = 50GB/day
  • 5 years: 50GB × 365 × 5 ≈ 90TB

Длина короткого URL

Сколько символов нужно для уникального идентификатора? Используем base62 (a-z, A-Z, 0-9):

ДлинаКомбинацииURLs (5 лет)
6 символов62⁶ = 56.8BНе хватит
7 символов62⁷ = 3.5T✓ Достаточно
8 символов62⁸ = 218TС запасом

Вывод: 7 символов base62 = 3.5 триллиона комбинаций. При 100M URL/день хватит на 96 лет.

Стратегии генерации ID

1
Hash + Collision Resolution

MD5/SHA256 от URL → взять первые 7 символов → проверить коллизию

✓ Плюсы:
  • Детерминистично (тот же URL = тот же hash)
  • Нет central point of failure
✗ Минусы:
  • Коллизии требуют retry + DB lookup
  • Сложно с custom aliases

2
Unique ID Generator + Base62
Рекомендуется

Получить уникальный числовой ID → конвертировать в base62

✓ Плюсы:
  • Гарантированно уникальный (без коллизий)
  • Простая логика
  • Легко поддерживать custom aliases
✗ Минусы:
  • Нужен ID generator (single point?)
  • Одинаковые URL могут дать разные short URLs

Варианты ID Generator

Auto-increment DB

Простое решение с auto_increment primary key.

⚠️ Single point of failure, не масштабируется

Multi-master DB

Два сервера: один генерирует чётные ID, другой — нечётные.

✓ Простое масштабирование, но ограничено количеством мастеров

UUID

128-bit уникальный идентификатор, генерируется на клиенте.

⚠️ Слишком длинный (36 символов), плохо для URL

Snowflake ID
Рекомендуется

64-bit ID: timestamp + datacenter + machine + sequence.

✓ Распределённый, сортируемый по времени, компактный

Snowflake

Twitter/X: Snowflake ID

Детальный разбор алгоритма генерации ID

Читать обзор

High-Level Architecture

Architecture Map

Click a flow to highlight
Client

Browser / App

Load Balancer

Edge routing

URL Service

Stateless API

Read path

Cache

Redis

Database

PostgreSQL / Cassandra

Write path

ID Generator

Snowflake

Database

PostgreSQL / Cassandra

Highlight a flow

Cache miss shown as a dashed line to the database.

Write flow
Read flow

Write Path

  1. 1. Клиент отправляет длинный URL
  2. 2. ID Generator выдаёт уникальный ID
  3. 3. Конвертируем ID в base62 → short URL
  4. 4. Сохраняем mapping в DB
  5. 5. Возвращаем short URL клиенту

Read Path

  1. 1. Клиент запрашивает short URL
  2. 2. Проверяем Cache (Redis)
  3. 3. Cache miss → запрос в DB
  4. 4. Обновляем Cache
  5. 5. HTTP 301/302 Redirect

301 vs 302 Redirect

301 Moved Permanently

Браузер кэширует редирект. Следующие запросы идут напрямую на target URL.

✓ Меньше нагрузки на сервер

✗ Нельзя отслеживать клики

302 Found
Рекомендуется

Браузер НЕ кэширует. Каждый клик проходит через сервер.

✓ Полная аналитика кликов

✓ Можно менять target URL

Data Model

urls table

ColumnTypeDescription
short_urlVARCHAR(7)Primary key, base62 encoded
original_urlTEXTОригинальный длинный URL
user_idBIGINTСоздатель ссылки (опционально)
created_atTIMESTAMPДата создания
expires_atTIMESTAMPTTL (null = бессрочно)

Deep Dive

Database Internals

Индексы, B-Trees и оптимизация для read-heavy workloads

Читать обзор

Caching Strategy

Read/Write ratio 10:1 делает кэширование критически важным. Используем Redis для хранения hot URLs.

Стратегия

  • Cache-aside: читаем из кэша, при miss идём в DB
  • LRU eviction: вытесняем редко используемые URL
  • Write-through: при создании сразу пишем в кэш

Cache Size

20% daily reads × avg URL size

= 200M × 500B = 100GB

→ Redis cluster с репликацией

CDN

Content Delivery Network

Geo-distributed caching для глобальных систем

Читать обзор

Выбор базы данных

PostgreSQL

  • ✓ ACID гарантии
  • ✓ Простота использования
  • ✓ Хорошо для средних нагрузок
  • ✗ Сложнее горизонтальное масштабирование

Cassandra / DynamoDB
Для масштаба

  • ✓ Линейное горизонтальное масштабирование
  • ✓ Высокая доступность (no single point)
  • ✓ Оптимизирован для write-heavy
  • ✗ Eventually consistent

Ключевые выводы для интервью

Покажите понимание

• Base62 encoding и расчёт длины URL

• Trade-offs между hash и ID generator

• 301 vs 302 для аналитики

• Read-heavy system → фокус на кэширование

Частые follow-up вопросы

• Как обрабатывать duplicate URLs?

• Как реализовать custom aliases?

• Как удалять expired URLs?

• Как защититься от abuse?

Связанные главы

Чтобы отмечать прохождение, включи трекинг в Настройки