Основная архитектура
Сервис сокращения URL должен справляться с асимметричным трафиком — чтения (редиректы) значительно превосходят по объему записи (создание URL). Проектные решения должны в первую очередь оптимизировать высокую пропускную способность чтения.
Генерация уникального короткого кода
Существует три основных подхода:
- Base62-кодирование автоинкрементного ID (символы
a-z, A-Z, 0-9)
- Хеширование исходного URL (например, MD5/SHA256) с последующим выделением подстроки
- Предгенерированные ID из распределённого сервиса (например, Twitter Snowflake)
Base62-кодирование распределённого счётчика в целом предпочтительнее благодаря предсказуемости и отсутствию коллизий.
Хранение данных
Храни маппинги short_code → original_url в хранилище ключ-значение (например, Redis, DynamoDB) для быстрого поиска. Реляционная БД может дополнять его для аналитики, метаданных об истечении срока и информации о владельце.
Стратегия редиректа
- Используй 302 (временный) редирект, чтобы сохранить точность аналитики — браузеры не будут кешировать его навсегда
- Используй 301 (постоянный) только если аналитика не нужна и кеширование допустимо
Кеширование для масштабирования
Применяй стратегию cache-aside с помощью Redis или Memcached:
- Популярные URL кешируются на CDN-уровне или на уровне приложения
- Процент попаданий в кеш обычно очень высокий благодаря распределению Зипфа (небольшое количество URL получает большую часть трафика)
Горизонтальное масштабирование
- Шардируй БД по префиксу короткого кода или диапазону хешей
- Разворачивай stateless серверы приложений за балансировщиком нагрузки
- Используй CDN для обслуживания редиректов по самым популярным ссылкам
Предотвращение злоупотреблений
- Ограничивай частоту создания URL по IP или API-ключу
- Проверяй целевые URL по спискам вредоносных сайтов и фишинга
- Применяй политики истечения срока, чтобы автоматически чистить устаревшие маппинги
- Требуй CAPTCHA или аутентификацию при массовом создании ссылок