Спроектируйте сокращатель ссылок
Вопрос
Спроектируйте сервис коротких ссылок: пользователь отправляет длинный URL, получает короткий, переход по короткому ведёт на длинный. Нужна статистика переходов.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Требования: создать ссылку, редирект, статистика переходов, срок жизни; вне рамок кастомные домены; задержка редиректа малая, доступность высокая
Оценка нагрузки: 100 млн новых ссылок в месяц ≈ 40 RPS записи, чтение 100:1 ≈ 4 000 RPS, в пике ~10 000; 6 млрд ссылок за 5 лет по ~500 байт ≈ 3 ТБ
API: POST /links {url, ttl} → {code}; GET /{code} → 302 Location; GET /links/{code}/stats
Данные: таблица code → url, owner, created_at, expires_at; key-value доступ по коду, шардирование по коду; события переходов в ClickHouse
Компоненты: API за балансировщиком, генератор кодов (счётчик с выдачей диапазонов или случайный код с проверкой), Redis-кеш горячих кодов, очередь событий переходов
Узкие места: горячие ссылки (кеш, CDN), коллизии и перебор кодов (случайность, rate limit), 301 против 302, удаление просроченных, злоупотребления (фишинг)
Что могут спросить следом
- Как генерировать коды без коллизий на нескольких серверах?
- Почему 302, а не 301?
- Как защититься от перебора коротких кодов?
Разбор
Требования: создать короткую ссылку, редирект, статистика, срок жизни. Нагрузка: 100 млн ссылок в месяц, это около 40 RPS на запись, чтений в 100 раз больше, около 4 000 RPS и до 10 000 в пике. За 5 лет 6 млрд записей примерно по 500 байт, это около 3 ТБ, плюс реплики. API: POST /links возвращает код, GET /{code} отвечает 302, отдельный эндпоинт статистики. Код из 7 символов base62 даёт 3,5 трлн вариантов. Генерирую либо из счётчика, раздавая серверам диапазоны id, либо случайно с проверкой уникальности; случайный код ещё и не позволяет перебором найти чужие ссылки. Хранение: доступ только по коду, поэтому подойдёт шардированный PostgreSQL или key-value. Редирект читает Redis, промах идёт в БД. Каждый переход публикую в Kafka, аналитика считается в ClickHouse, чтобы не тормозить редирект. 302 нужен ради статистики. Узкие места: вирусные ссылки (кеш, локальный кеш), спам и фишинг (проверка URL по спискам, rate limit на создание), очистка просроченных фоновой задачей.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.