Получить доступ

Как перешардировать данные без простоя?

SeniorШардирование и распределение данных
Ещё спрашивают так:
  • Как добавить шарды в работающую систему?
  • Как перенести данные между базами без остановки сервиса?
  • Что такое двойная запись при миграции?
Коротко

Переносить данные по частям, пока система работает: копия + догоняющий поток изменений + переключение маршрутизации по одной части и проверка.

  • Заранее много логических шардов (слотов) на мало физических — переносится слот целиком, а ключи не пересчитываются
  • Копия снимком, затем догоняющая репликация изменений (CDC, логическая репликация)
  • Короткое переключение: запрет записи на слот на секунды, дождаться догонки, сменить маршрут

А ещё Двойная запись из приложения проще на словах, но с риском расхождений — нужна сверка

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Подготовка, которая делает решардинг дешёвым: разбить данные на много логических шардов (слотов) — 1024, 16384 — и раскладывать их по небольшому числу физических серверов через таблицу «слот → сервер». Тогда рост — это перенос части слотов на новый сервер, а функция ключ → слот не меняется. Так устроены Redis Cluster, Vitess, Citus, Kafka с партициями. Без этого hash % N → hash % 2N требует переезда почти всего.

Схема переноса одного слота (или диапазона):

  1. снимок — скопировать данные слота на новый узел, не останавливая запись в старый;
  2. догонка — применять изменения, произошедшие после снимка: поток из журнала базы (CDC, логическая репликация), с позиции, с которой делался снимок;
  3. сверка — сравнить объёмы и контрольные суммы по диапазонам;
  4. переключение — на короткое время запретить запись в слот (или поставить запросы на ожидание), дождаться, пока отставание станет нулевым, переключить маршрутизацию, снять запрет. Секунды недоступности записи для одного слота;
  5. уборка — удалить данные со старого узла после периода наблюдения; держать возможность отката.

Двойная запись из приложения — писать в старое и новое хранилище одновременно, читать из старого, потом переключить чтение. Проблемы: нет атомарности между двумя хранилищами (одна запись прошла, другая — нет), гонки при параллельных изменениях одной записи, нужно отдельно переносить старые данные. Если выбирать её — с идемпотентными записями, фоновой сверкой и исправлением расхождений. Поток из журнала базы надёжнее: порядок изменений сохраняется.

Маршрутизация во время переноса: прокси или библиотека знает карту слотов и её версию; клиент с устаревшей картой получает ответ «перенаправление» (MOVED/ASK в Redis Cluster) и обновляет карту.

Риски и защита: нагрузка от копирования на рабочую базу (ограничивать скорость), рост отставания, дубли при повторах (идемпотентность), запросы, которые читали данные в момент переключения. Переносить по одному слоту, начиная с малонагруженных, с метриками и возможностью остановить.

Пример

16 физических серверов, 4096 слотов (по 256 на сервер). Добавляем 4 сервера:
переносим по ~51 слоту с каждого старого на новые — 20% данных.
Слот: снимок → догонка по WAL → отставание < 100 мс → запись в слот на паузе 1–2 с
→ карта слотов v42 → v43 → снятие паузы → удаление копии через сутки.

Что хотят услышать

  • Логические шарды или слоты поверх физических как основа.
  • Этапы: снимок, поток изменений, сверка, короткое переключение.
  • Плюсы и риски двойной записи.
  • Маршрутизация с версией карты и перенаправлениями.

Частые ошибки

  • Предлагать остановить сервис на время переноса как единственный вариант.
  • Делать двойную запись без сверки и идемпотентности.

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем