Недавно решали на работе задачу миграции хранилища данных. Оно у нас одно из крупнейших в отрасли, по крайней мере, в нашей стране. Оказалось, что даже на этапе планирования всё не так просто, как кажется. Делюсь проблемами, их решениями и получившейся дорожной картой.
Привет, Хабр! Меня зовут Татьяна Сеземина. Я — директор портфеля проектов Т1 ИИ и руковожу проектами разработки и миграции больших хранилищ данных, сейчас мои проекты касаются отраслей ритейла и логистики. Каждый проект миграции длится от года до нескольких лет. Одна из моих команд столкнулась с необходимостью детального планирования длительной многолетней миграции хранилища, вплоть до каждого объекта. Расскажу, почему так произошло и как такую проблему решать.
Вступление
То, что хранилище нужно мигрировать на новую платформу, стало понятно в 2024 году. Миграцию больше нельзя было откладывать из-за необходимости дальнейшего масштабирования решения и роста объема данных. На существующей западной проприетарной платформе сделать это было невозможно из-за санкций.
Поэтому решили мигрировать на одну из российских платформ. Намеренно не называю, на какую именно,, так как для нашей задачи это не имеет принципиального значения. Изложенные подходы можно применить для планирования миграции с любой платформы данных на любую другую.
Вместе со мной в этой задаче активно участвовала команда:
Новруз Мамедов, архитектор данных;
Алексей Кулагин, системный аналитик;
Евгений Ларин, системный архитектор;
Сергей Стрельников, разработчик.
Чтобы переехать и ничего не потерять по дороге, мы начали с обследования хранилища и построили детальный план миграции. Об этой задаче и поговорим подробнее.
Для ее достижения мы собрали подробную информацию о каждом значимом объекте, включая корпоративные «песочницы». Всех объектов хранилища, включая «песочницы», оказалось очень много — более 9 000.
Чтобы сохранить при миграции привычную бизнес-пользователям функциональность, выявили связи между объектами и их зависимости друг от друга. Связей было ещё больше, чем объектов. Получилась настоящая паутина, включающая в себя в том числе объекты систем-источников и связи с ними.
Дерево взаимосвязей можно представить (и часто это бывает удобным) в виде таблицы. Пример такой таблицы приведу в разделе «Обследование хранилища данных».
Исходные данные
Мы начали строить очень подробный план с детализацией до конкретного объекта хранилища данных. И уже на этом этапе начали всплывать проблемы. Оказалось, у нашего огромного хранилища данных, объемом около 1 ПТб, частично не описана функциональность. Конечно, в этом нет ничего удивительного. У любого хранилища данных, особенно если оно развивается десятки лет, накапливаются проблемы, и мы — не исключение. Помимо недостаточного описания, у нас:
отсутствовал атрибутный data lineage в полном объеме;
отсутствовала матрица работ, необходимых для миграции.
Сложно было понять, как к этому подступиться. И мы решили начать с восстановления описания зависимостей объектов внутри хранилища.
Обследование
Сначала выявили неточности в существующем описании. Проблема в том, что необходимые данные были разбросаны по разным бизнес-подразделениям. Собрать всех сотрудников обладающих нужной информацией и сразу получить от них все, что нужно, было невозможно. Поэтому мы составили опросники. Ниже привожу пример информации, которую мы собирали по каждой системе потребителе/отчету.
Предоставляемая информация об отчете |
ID Отчета Наименование отчета Назначение отчета Бизнес-область отчета Ссылка на BI-портал Подразделение-владелец отчета Контактная информация о владельце отчета Требования ко времени готовности данных Глубина хранения данных Частота обновления данных Глубина обновления данных Требования к Data Quality Требования к разделению прав доступа Дополнительные требования |
---|---|
Информация об источниках данных для отчета, детализированная до атрибутов |
ID Отчета Наименование отчета Показатель отчета Соответствующий показателю отчета объект хранилища и атрибут этого объекта |
Анкета о системе-потребителе |
Наименование системы Наименование подсистемы Бизнес-область системы Назначение системы (в каких процессах участвует) Подразделение-владелец системы Контактная информация о владельце системы |
Информация об источниках данных для системы-потребителя, детализированная до объектов хранилища |
Наименование системы Наименование подсистемы Объект хранилища Требования ко времени готовности данных Глубина хранения данных Частота обновления данных Глубина обновления данных |
Пришлось делать несколько шаблонов, так как запрашиваемые данные для разных бизнес-подразделений тоже различались. Зато с помощью опроса нам удалось узнать какие объекты хранилища данных используются в качестве источников корпоративной отчетности, в интеграции с системами-потребителями и других целях. В результате у нас появился список объектов, на которых базируется каждая бизнес-функциональность. Так одной проблемой стало меньше.
После этого можно было разбираться со второй проблемой. Существующий data lineage был не полным, в нем следовало закрыть «разрывы». Для этого на основе существующих метаданных разработали универсальный алгоритм формирования дерева зависимости (data lineage) для любого объекта хранилища до источника данных.
Дерево зависимостей мы представили в виде таблицы. Ниже схематичный пример такой таблицы без упоминания названий конкретных слоев, в каждой компании их набор будет свой:
Система-источник |
Слой хранилища 1 |
... |
Слой хранилища N |
Система- потребитель / Отчет |
Объект источника |
Объект слоя 1 |
... |
Объект слоя N |
Отчет |
и т.д. |
... |
... |
... |
... |
В процессе, благодаря алгоритму, мы выявили и устранили «разрывы» в data lineage некоторых объектов. А улучшение технического качества метаданных стало приятным побочным эффектом наших работ.
Также алгоритм выявил существенное количество витрин, формирующихся непромышленным способом, то есть в «песочницах». Это позволило уточнить рамки работ, и «опромышливание» таких витрин стало одной из задач проекта миграции.
Таким образом, одним из слоев нашего хранилища стали «песочницы».
Информация из data lineage дала возможность классифицировать все объекты хранилища, как объекты одного из слоев:
Слой сырых данных - RAW;
Детальный слой - DDS;
Слой базовых витрин - BaseMart;
Слой бизнес-витрин - BusinessMart;
«Песочницы» - SandBoxes.
В итоге обследование позволило описать все имеющиеся зависимости в хранилище данных, и можно было двигаться дальше.
Справочник работ, драйверы трудозатрат и метрики Холстеда
Нам оставалось решить ещё одну важную проблему и подготовить матрицу работ, необходимых для миграции. Сам список работ получили из множества интервью с экспертами департамента управления данными и бизнес-подразделений. Получился подробный список с полной детализацией работ на всех этапах создания КХД по слоям.
Фрагмент списка работ (как пример) приведен ниже:
Работа |
Разработка логической модели данных |
Архитектурное review логической модели данных |
Согласование логической модели данных |
Создание прототипа трансформации данных |
Заполнение source-to-target |
Разработка потоков загрузки и трансформации данных |
Проведение приемо-сдаточных испытаний |
Развертывание релиза в промышленной среде |
и т.д. |
Для каждого вида работ в списке мы определили драйвер, то есть сущность, которую можно посчитать, и в зависимости от которой можно измерять трудозатраты.
Пример связи списка работ и драйверов:
Работа |
Драйвер |
Создать ЛМД в Power Designer |
Количество атрибутов таблицы DDS |
Сформировать S2T |
Количество таблиц DDS |
Сформировать требования / методологию формирования витрин |
Количество бизнес-витрин |
и т.д. |
Метрики трудозатрат были определены:
для каждого вида работ;
для каждой роли (системный аналитик, разработчик, архитектор, бизнес-аналитик, аналитик Data Governance);
для каждого драйвера.
Теперь, имея точный список объектов хранилища, видов работ и драйверов, а также метрики по ролям, мы могли посчитать трудозатраты.
Стоит отметить, что для большинства видов работ метрики трудозатрат задаются экспертно в виде констант. Но есть такой вид работы как создание прототипа в виде SQL-кода на основе анализа кода хранимых процедур в текущем КХД. В этом случае трудозатраты будут зависеть от «сложности» кода (количества сущностей, атрибутов, количества операций) и не могут быть заданы константой.
Для оценки сложности кода и расчета трудозатрат на его миграции Алексей Кулагин и Сергей Стрельников предложили использовать и реализовали алгоритм на основе метрик Холстеда, адаптировав его для SQL.
SEL
Cnt_method AS calc_name -- Наименование способа расчета (наименование процедуры, вьюхи)
,tablekind AS calc_type -- Тип расчета (V-вьюха, P-процедура)
,Count(DISTINCT CASE WHEN token_type = 'Operation' THEN metric_name ELSE NULL END) AS nu_op -- Количество уникальных служебных слов (операций)
,Count(DISTINCT CASE WHEN token_type in ( 'Operand','Common') THEN metric_name ELSE NULL END) AS nu_opd -- Количество уникальных операндов (столбцы, таблицы)
,Sum(CASE WHEN token_type = 'Operation' THEN metric_value ELSE NULL END) AS n_sm_op -- Общее число служебных слов (операций)
,Sum(CASE WHEN token_type in ( 'Operand','Common') THEN metric_value ELSE NULL END) AS n_sm_opd -- Общее число операндов (столбцы, таблицы)
,nu_op+nu_opd AS n_dict -- Словарь скрипта = nu_op+nu_opd
,n_sm_op+n_sm_opd AS n_length -- Длина скрипта = n_sm_op+n_sm_opd
,n_length*(Log(n_dict)/Log(2)) AS v_length -- Обьем скрипта = n_length*log2(n_dict)
,(nu_op*n_sm_opd)/(2*nu_opd) AS d_length -- Сложность разработки = (nu_op*n_sm_opd)\(2*nu_opd)
,d_length*v_length AS e_length -- Усилия при разработке = d_length*v_length
,18 AS k_psy -- Психологический фактор (От 5 до 20, берем 13)
,e_length/k_psy AS t_length -- Трудозатраты = e_length\k_psy
,t_length/3600 AS cost_mh -- Трудозатраты в часах
,NULL AS ctg_complex_name -- Категория сложности зависит от d_length и максимально сложного способа расчета из ctg_complex (пока оставляем пусто)
FROM migration.t_obj_complexity
Использование известных отраслевых метрик дало возможность упростить согласование дорожной карты миграции всеми заинтересованными сторонами.
Теперь у нас были все взаимосвязи внутри хранилища и оценка всех работ для каждого объекта по ролям. Оставалось разбить хранилище на блоки таким образом, чтобы проводить миграцию поэтапно и последовательно вводить функциональность в эксплуатацию.
Разбиение хранилища на блоки миграции
Мы разбили хранилище на слои, но этого оказалось недостаточно для детального планирования, так как хранилище очень большое и за его разные части отвечают разные специалисты на уровне бизнес-подразделений. Поэтому мы начали разбивать все объекты хранилища по функциональным блокам миграции:
Выявили перечень крупных предметных областей, на которые разделено текущее хранилище данных.
Каждую из крупных предметных областей разделили на более мелкие множества объектов по их функциональному назначению — на, так называемые, функциональные блоки миграции. Например, у нас были следующие функциональные блоки: ассортимент, чеки, операции, и т.д.
Все объекты следующих слоев RAW, DDS, BaseMart мы отнесли к конкретному функциональному блоку миграции.
Разбитые объекты витринного слоя BusinessMart и «песочниц» SandBoxes на функциональные блоки оказалось невозможно. Причина в нашем хранилище. Любая бизнес-витрина собиралась из данных разных функциональных блоков. Также, к сожалению, в ходе предварительного обследования нам не удалось выявить явные бизнес-приоритеты для миграции витрин.
Тогда мы пошли другим путем и разбили объекты витринного слоя на, как мы их назвали, пулы миграции. Объединение в пулы происходило так:
Для каждого объекта витринного слоя и слоя «песочниц» построили полное дерево зависимостей вплоть до объектов систем-источников.
Все объекты витринного слоя и слоя «песочниц» отсортировали так, что до каждого конкретного объекта в этом списке шли все объекты витринного слоя, на которые он ссылается прямо или опосредованно (то есть через другие объекты).
Для каждого объекта были заранее известны значения необходимых на его миграцию трудозатрат. Мы разбили этот отсортированный список на группы так, чтобы в каждой группе было примерно одинаковое количество трудозатрат.
Эти группы мы и назвали пулами миграции витрин.
Наше обследование показало какие отчеты и системы-потребители «питаются» из каждой витрины. Поэтому мы могли точно сказать, какие отчеты и потоки в системы-потребители можно мигрировать на новую платформу после миграции каждого конкретного пула.
Такой подход с разбиением витрин на пулы очень важен. Именно он является критерием поэтапной миграции при составлении дорожной карты.
Такая механистическая разбивка витрин, как ни странно, привела к их объединению в группы по родственному признаку.
После того как мы выявили все зависимости объектов, трудозатраты на каждый вид работ миграции и разбили объекты на группы, в которых будем мигрировать. Наконец можно было приступить к формированию дорожной карты миграции.
Финальная дорожная карта миграции
У финальной карты два больших последовательных этапа:
Миграция ядра хранилища - миграция слоев RAW, DDS и BaseMart;
Миграция витринного слоя – BusinessMart и SandBoxes.
Эти этапы фактически идут последовательно, с небольшим «нахлестом» в один месяц. То есть сначала полностью завершается миграция ядра хранилища, и потом начинается миграция витринного слоя.
Миграция ядра хранилища разбита на функциональные блоки. Каждый блок можно мигрировать независимо. Поэтому в нашем случае часть функциональных блоков разрабатывали параллельно, чтобы сократить общий срок проекта миграции.
Все работы по миграции ядра в рамках функционального блока объединили в четыре этапа:
системный анализ (наведение порядка и закрытие неточностей в документации);
миграция RAW-слоя;
миграция DDS-слоя;
миграция BaseMart-слоя.
Схематично последовательность выполнения выглядит так:
То есть системный анализ и миграция слоя RAW идут параллельно. Затем идут последовательно миграции слоя DDS и слоя BaseMart.
Дорожная карта миграции ядра хранилища выглядит так:
Сценарий |
Консервативный |
Роль |
Системный аналитик |
Вид ресурса |
Подрядчик |
Наименование показателя |
FTE |
Январь 2025 |
Февраль 2025 |
Март 2025 |
Апрель 2025 |
Май 2025 |
Июнь 2025 |
Июль 2025 |
и т.д. |
|
Итого |
*** |
*** |
*** |
*** |
*** |
*** |
*** |
|
Функциональный блок 1 |
||||||||
- Системный анализ |
*** |
*** |
||||||
- Миграция RAW |
*** |
|||||||
- Миграция DDS |
*** |
*** |
*** |
*** |
||||
- Миграция BaseMart |
||||||||
Функциональный блок 2 |
||||||||
- Системный анализ |
*** |
*** |
*** |
|||||
- Миграция RAW |
*** |
|||||||
- Миграция DDS |
*** |
*** |
*** |
|||||
- Миграция BaseMart |
||||||||
Функциональный блок 3 |
||||||||
- Системный анализ |
||||||||
- Миграция RAW |
*** |
|||||||
- Миграция DDS |
*** |
*** |
*** |
|||||
- Миграция BaseMart |
||||||||
и т.д. |
Миграция витринного слоя начинается после окончания миграции ядра и строится на таких принципах:
Каждый следующий пул зависит от всех предыдущих и не включает трудозатраты объектов предыдущих пулов.
В плане миграции пулы идут строго последовательно с небольшим «нахлестом» в месяц.
Этот «нахлест» — за счет старта работ по системному анализу до того, как закончатся работы по предыдущему пулу витрин.
Ввод функционала витрин в эксплуатацию идет поэтапно: один пул после другого, а не вся функциональности в конце разом.
В теории все объекты можно ввести в промышленную эксплуатацию в конце разом. Но важно исходить из здравого смысла, так как на одной чаше весов сроки, а на другой — необходимость привлечения разово большого числа специалистов и трудности управления слишком большой командой. А поэтапная миграция позволяет вводить и отключать части огромного хранилища данных с наименьшими рисками и снизить нагрузку на техническую поддержку в моменте.
Дорожная карта миграции витринного слоя:
Сценарий |
Консервативный |
Наименование показателя |
FTE |
Декабрь 2025 |
Январь 2026 |
Февраль 2026 |
Март 2026 |
Апрель 2026 |
Май 2026 |
Июнь 2026 |
и т.д. |
|
Пул 1 |
*** |
*** |
*** |
|||||
Пул 2 |
*** |
*** |
*** |
|||||
Пул 3 |
*** |
*** |
*** |
|||||
Пул 4 |
*** |
*** |
*** |
|||||
Пул 5 |
*** |
*** |
*** |
|||||
Пул 6 |
*** |
*** |
||||||
Пул 7 |
*** |
|||||||
Пул 8 |
||||||||
и т.д. |
Наша дорожная карта на всех ее этапах строится в разрезе нескольких сценариев, оцениваются различные виды ресурсов и роли.
Отличительные особенности нашего плана:
Функционал старого хранилища выводится из эксплуатации поэтапно так же, как и вводится функционал нового, импортозамещенного, хранилища. Это позволяет распределять нагрузку команды во времени.
Планирование детализировано до каждой роли для всех видов работ каждого слоя хранилища данных.
Наш план легко пересчитывается при изменении объема и состава работ.
Плюсы нашей дорожной карты
Такой подход позволил сформировать критерии поэтапной миграции функционала и старта его работы на новой платформе. Для каждого пула известен список отчетов и потоков с системами-потребителями, готовых к переезду на целевую платформу после миграции конкретного пула.
Поэтапная миграция позволила раньше вывести из эксплуатации часть функционала на старой платформе и сэкономить средства.
Наш план достаточно гибок и легко пересчитывается при изменении ряда параметров:
Дата начала миграции функционального блока ядра;
Длительность миграции функционального блока ядра;
Дата готовности источников для подключению к слою RAW.
Было рассчитано несколько сценариев плана в зависимости от готовности подключения источников в RAW. Сценарии зависели от следующих вариантов:
ранняя дата начала миграции слоя RAW$
поздняя дата начала миграции RAW (самая поздняя дата, когда мы можем начать подключение источников).
Таким образом, изменив некоторые параметры вы можете подстроить эту дорожную карту под свое хранилище.
Итоги
Формирование дорожной карты позволило нам выявить и устранить проблемы в старом хранилище, а не переносить их в новое. И получить следующие преимущества:
Управлять миграцией максимально гибко, легко пересчитывать сроки, основные вехи проекта при изменении состава объектов или приоритетов их миграции.
Строить оптимистичные, реалистичные и пессимистичные планы.
Заранее увидеть узкие места необходимой для миграции численности персонала.
Детально планировать привлечение специалистов в разрезе каждой роли.
Сформировать критерии миграции каждого блока отчетности на новый импортонезависимый стек.
И наконец, провести последующую миграцию в максимально сжатые сроки при оптимальном задействовании ресурсов.