База данных перестаёт справляться с нагрузкой и объёмом. Расскажите про репликацию и шардирование: когда что применять, как выбрать ключ шардирования и что делать с решардингом.
Короткий ответ
- Репликация масштабирует чтения и даёт отказоустойчивость
- Шардирование масштабирует записи и объём данных
- Асинхронная реплика отстаёт — читатель может не увидеть свою запись
- Ключ шардирования должен равномерно распределять нагрузку
- Хэш-шардирование ровнее, диапазонное сохраняет сканы по диапазону
- Горячие ключи лечат солью или выделенным шардом
- Consistent hashing упрощает добавление узлов при решардинге
Сначала реплики для чтений, затем шардирование по ключу с равномерным распределением; главные риски — отставание реплик, горячие шарды, кросс-шардовые запросы и решардинг.
Как сказать вслух
пример ответаЯ разделю проблему: если не хватает чтений — добавляю реплики, если упираемся в записи или объём — шардирую. Для шардирования главный вопрос — ключ: он должен размазывать нагрузку равномерно и совпадать с основным паттерном доступа. Про решардинг скажу сразу, потому что менять ключ на живой системе — самое дорогое.
Подробный ответ
Основной ответ
Репликация — копии данных на нескольких узлах: лидер принимает записи, реплики обслуживают чтения и подхватывают роль при отказе. Асинхронная репликация дешевле, но вводит lag: пользователь может не увидеть собственную запись с реплики — лечится read-your-writes (чтение своих данных с лидера или закрепление сессии). Шардирование — горизонтальное разбиение данных по ключу. Хэш от ключа даёт равномерность, но убивает диапазонные сканы; диапазонное разбиение сохраняет их, но склонно к горячим шардам (свежие даты). Ключ выбирают под главный паттерн доступа: для мультитенантной CRM — tenant id, чтобы запросы тенанта не трогали чужие шарды. Решардинг упрощает consistent hashing с виртуальными узлами либо заранее созданные логические партиции, которые переезжают целиком.
Ключевые моменты
- Порядок действий. Сначала индексы, кэш и реплики — шардирование добавляет кросс-шардовые запросы, распределённые транзакции и сложный решардинг, его берут последним.
- Выбор ключа. Хороший ключ равномерно делит и данные, и трафик, и покрывает основной паттерн запросов; монотонный ключ (автоинкремент, timestamp) концентрирует записи в одном шарде.
- Горячий шард. Один гигантский тенант или вирусная сущность перегревает шард; решения — соль в ключе, разбиение сущности, вынос на отдельный узел.
- Решардинг. Создать заранее много логических шардов (например, 4096) и маппить их на физические узлы — перенос меняет маппинг, а не перехэширует все данные.
Практический контекст
Интервьюер ждёт, что вы не броситесь шардировать сразу, обсудите выбор ключа через паттерны доступа и честно назовёте цену: потерю кросс-шардовых join и транзакций, сложность миграции. Уточните: соотношение чтений и записей, есть ли сущности-гиганты, нужны ли глобальные запросы по всем шардам (их обычно уводят в отдельное аналитическое хранилище).
Частые ошибки
- Предлагают шардирование до того, как исчерпаны индексы, кэширование и реплики
- Выбирают монотонный ключ (дата, автоинкремент) и получают один горячий шард на запись
- Не упоминают отставание реплик и сценарий «пользователь не видит свою запись»