@quest2017

Как реализовать миграцию данных / виртуальных шардов?

Кто поверх SQL делал миграцию данных / шардов online (наживую) поделитесь плиз идеями!

как я понимаю нужно завести справочник/функцию который говорит на каком сервере лежит конкретный ключ (запись с конкретным идентификатором). далее процесс миграции должен монопольно захватывать ключи на сервере «A» (select for update), атомарно прятать ключи в скрытую таблицу и не атомарно перемещать на сервер «B» в скрытую таблицу, где атомарно их делать доступными и менять в справочнике местоположение ключей с сервера «A» на сервер «B». Скрытая таблица по идее нужна потому как перемещение ключей между серверами не атомарно и может случится так что в какой-то момент на сервере «B» будет только часть ключей (если мы перемещаем не просто единичный ключ, а множество ключей - виртуальный шард).

как быть если в то время когда началась миграция клиент уже пришел на сервер «A» и не нашел данные? тупо долбится то в справочник то на сервер «A» пока в справочнике не обновится адрес сервера и клиент не зайдет на новый сервер «B»? Может придумать тут какую-то нотификацию вместо поллинга? Как ее сделать?

Как вы строите справочник с соответствием ключа серверу либо ключа виртуальному шарду а виртуального шарда серверу? По какому алгоритму и с помощью каких инструментов?

Читал в частности историю где люди ушли от виртуальных шардов просто к соответствию ключа серверу, в чем это соответствие хранить?

Заранее спасибо за идеи и ответы!
  • Вопрос задан
  • 136 просмотров
Пригласить эксперта
Ответы на вопрос 1
@rPman
Делайте идентификаторы такими, чтобы можно было гарантированно их разбить на группы, например с шагом N (макс количество серверов) а стартовое значение сиквенсов у каждого сервера разное (от 1 до N) - назовем это стартовое число 'модуль индекса', таким образом вы сгруппируете данные, и перемещать их можно будет группами, по принадлежности индекса своему модулю индекса (получить его можно взял модуль от индекса по N, если N- степень двойки, то достаточно будет битовой маски).

Вам достаточно хранить, какой индекс модуля размещается на каком физическом сервере, и перемещать данные сразу этими группами, естественно в пределах одной транзакции (открываете транзакцию на обоих серверах, льете данные, по окончанию, комитите на одном, отмечаете в таблице что данные переехали, удаляете, комитите на другом.

Чтобы в процессе переноса на сервере данные не появлялись, сделайте механизмы, отключающие эту ноду от создания новых записей (этакий read/write only) и логирование факта модификации записи по id (дата последнего изменения в каждой таблице - либо используйте штатные механизмы низкоуровнего лога sql-сервера), т.е. таблица, которая будет у вас отвечать за информацию о размещении групп на серверах должна содержать содержать и этот флаг. И да, эту таблицу реплицируйте между серверами штатными инструментами sql-сервера.

Кстати, точно помню, в oracle можно было настроить репликацию данных по условию... не удивлюсь если это есть и у других, тогда за перенос данных между серверами будет отвечать внутренний механизм sql-сервера - это на порядок эффективнее и надежнее чем самописные инструменты.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы