Кейс: URL shortener
↑ 8.4 Backend System Design · ← Предыдущая · → Следующая
Зачем это на собесе
Классическая задача. Показывает генерацию ключей, кэш и оценку нагрузки.
Объяснение
Требования: создать короткую ссылку, редирект по ней, опционально свой алиас, срок жизни, статистика кликов. Нефункциональные: редирект быстро (< 50 мс), высокая доступность, чтения ≫ записей (100:1), данные хранятся годами.
Оценка: 100 млн ссылок в месяц → ~40 записей/с, ~4 000 RPS чтений (пик 20 000). Хранение ≈ 3 ТБ за 5 лет.
API:
POST /links { "url": "https://…", "alias": "my-link", "ttl": "30d" } → 201 { "short": "https://sho.rt/aB3xY9" }
GET /{code} → 301/302 Location: https://…Генерация кода (7 символов Base62 ≈ 62⁷ ≈ 3,5 трлн комбинаций):
| Способ | Плюсы | Минусы |
|---|---|---|
| Хэш URL (MD5 → первые 7 символов) | одинаковый URL — одинаковый код | коллизии, нужна проверка |
| Счётчик + Base62 | без коллизий, коротко | предсказуемо; счётчик — единая точка (диапазоны на инстанс) |
| Случайный ID + проверка уникальности | непредсказуемо | повторные попытки при коллизии |
| Заранее сгенерированные ключи (Key Generation Service) | быстро, без коллизий | отдельный сервис |
Схема:
flowchart LR C[Клиент] --> LB[Балансировщик] --> A[Stateless API] A --> R[(Redis кэш)] A --> DB[(БД: code → url)] A -. клики .-> KKafka --> CH[(ClickHouse)]
- Хранилище: key-value (DynamoDB/Cassandra) или PostgreSQL с индексом по
code; шардирование по хэшу кода. - Кэш Redis для горячих кодов (LRU): попадание > 90%.
- 301 (постоянный) кэшируется браузером и снижает нагрузку, но теряет статистику; 302 — точнее считает клики.
- Клики отправляются асинхронно в Kafka → агрегация в ClickHouse.
- Удаление просроченных ссылок — фоновая задача/TTL.
Нюансы и подводные камни
- Защита от злоупотреблений: фишинг-ссылки, rate limiting, проверка URL.
- Предсказуемые коды позволяют перебирать чужие ссылки.
- Коллизии хэша при высокой нагрузке.
- Единая точка отказа в генераторе счётчика.
- Кэширование негативных результатов (несуществующие коды).
Практика
- Реализуйте генерацию Base62 из диапазонов счётчика.
- Оцените hit-rate кэша на реальном распределении запросов.
- Опишите деградацию при падении Redis и БД.
Вопросы с ответами
Как гарантировать уникальность кода?
Счётчик с выдачей диапазонов инстансам или проверка уникальности при случайной генерации.
301 или 302?
301 кэшируется и разгружает сервис, 302 позволяет считать клики; выбор по требованиям.