Как перешардировать данные без простоя?
- Как добавить шарды в работающую систему?
- Как перенести данные между базами без остановки сервиса?
- Что такое двойная запись при миграции?
Переносить данные по частям, пока система работает: копия + догоняющий поток изменений + переключение маршрутизации по одной части и проверка.
- Заранее много логических шардов (слотов) на мало физических — переносится слот целиком, а ключи не пересчитываются
- Копия снимком, затем догоняющая репликация изменений (CDC, логическая репликация)
- Короткое переключение: запрет записи на слот на секунды, дождаться догонки, сменить маршрут
А ещё Двойная запись из приложения проще на словах, но с риском расхождений — нужна сверка
Подробно
Подготовка, которая делает решардинг дешёвым: разбить данные на много логических шардов (слотов) — 1024, 16384 — и раскладывать их по небольшому числу физических серверов через таблицу «слот → сервер». Тогда рост — это перенос части слотов на новый сервер, а функция ключ → слот не меняется. Так устроены Redis Cluster, Vitess, Citus, Kafka с партициями. Без этого hash % N → hash % 2N требует переезда почти всего.
Схема переноса одного слота (или диапазона):
- снимок — скопировать данные слота на новый узел, не останавливая запись в старый;
- догонка — применять изменения, произошедшие после снимка: поток из журнала базы (CDC, логическая репликация), с позиции, с которой делался снимок;
- сверка — сравнить объёмы и контрольные суммы по диапазонам;
- переключение — на короткое время запретить запись в слот (или поставить запросы на ожидание), дождаться, пока отставание станет нулевым, переключить маршрутизацию, снять запрет. Секунды недоступности записи для одного слота;
- уборка — удалить данные со старого узла после периода наблюдения; держать возможность отката.
Двойная запись из приложения — писать в старое и новое хранилище одновременно, читать из старого, потом переключить чтение. Проблемы: нет атомарности между двумя хранилищами (одна запись прошла, другая — нет), гонки при параллельных изменениях одной записи, нужно отдельно переносить старые данные. Если выбирать её — с идемпотентными записями, фоновой сверкой и исправлением расхождений. Поток из журнала базы надёжнее: порядок изменений сохраняется.
Маршрутизация во время переноса: прокси или библиотека знает карту слотов и её версию; клиент с устаревшей картой получает ответ «перенаправление» (MOVED/ASK в Redis Cluster) и обновляет карту.
Риски и защита: нагрузка от копирования на рабочую базу (ограничивать скорость), рост отставания, дубли при повторах (идемпотентность), запросы, которые читали данные в момент переключения. Переносить по одному слоту, начиная с малонагруженных, с метриками и возможностью остановить.
Пример
16 физических серверов, 4096 слотов (по 256 на сервер). Добавляем 4 сервера:
переносим по ~51 слоту с каждого старого на новые — 20% данных.
Слот: снимок → догонка по WAL → отставание < 100 мс → запись в слот на паузе 1–2 с
→ карта слотов v42 → v43 → снятие паузы → удаление копии через сутки.Что хотят услышать
- Логические шарды или слоты поверх физических как основа.
- Этапы: снимок, поток изменений, сверка, короткое переключение.
- Плюсы и риски двойной записи.
- Маршрутизация с версией карты и перенаправлениями.
Частые ошибки
- Предлагать остановить сервис на время переноса как единственный вариант.
- Делать двойную запись без сверки и идемпотентности.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Остановить систему на время переноса данных
- ✗Пересчитать hash % N для всех ключей одномоментно
- ✓Копия, поток изменений и переключение
- ✗Перешардирование не требует проверки данных после переноса
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.