В последние годы мы видим, как инженерия данных всё больше сливается с индустрией DevOps. В обоих этих направлениях для доставки надёжных цифровых продуктов клиентам используется облачная инфраструктура, контейнеризация, CI/CD и GitOps. Это схождение в плане использования одного набора инструментов заставило многих думать, что инженерия данных не имеет значительных отличий от инженерии программного обеспечения. Как следствие, первая оказывается «несовершенной», поскольку дата-инженеры отстают с внедрением эффективных практик разработки ПО.

Но такая оценка ошибочна. Несмотря на то что в обработке данных и разработке ПО используется много общих инструментов и практик, между ними есть ряд существенных отличий. Игнорирование этих отличий и управление командой дата-инженеров по аналогии с командой разработки ПО является ошибкой. Так что цель данной статьи – подчеркнуть некоторые уникальные проблемы в инженерии данных и пояснить, почему в этой области иногда требуется особый подход.

Конвейеры данных – это не приложения


Разработка ПО подразумевает создание приложений. В контексте этой статьи термин приложение будет иметь очень широкий смысл, подразумевая как сайт, так и десктопное приложение, API, игру, микросервис, библиотеку и прочее. Объединяет же все эти виды приложений то, что они:

  • Предоставляют пользователям ценность, предлагая новую модель взаимодействия. В игру можно играть, сайт можно просматривать, API можно использовать в другом ПО.
  • Обладают рядом преимущественно независимых возможностей. У сайта может расти количество страниц, в игре может увеличиваться число уровней или доступных персонажей, в API могут добавляться новые конечные точки. В итоге получается, что приложение никогда не является поистине законченным.
  • Мало работают с создаваемыми ими состояниями. Состояние предназначено для поддержки приложения, и управление им обычно возлагается на внешнюю систему. Смысл в том, чтобы основная часть ПО работала без использования состояний. Веб-приложение можно в любой момент закрыть и запустить заново — его состоянием управляет база данных, выполняющаяся в отдельном процессе.
  • Слабо связаны с другим ПО и сервисами. Хорошее ПО должно функционировать независимо в любой среде, что объясняет популярность микросервисов и контейнеров.

Если же говорить о дата-инженерах, то они занимаются построением конвейеров данных. Такие конвейеры получают данные от их создателя, трансформируют эти данные и передают потребителю. Обычно стоит цель автоматизировать работу этих конвейеров по расписанию, чтобы датасеты периодически обновлялись новыми данными. Подобно приложениям — конвейеры обычно являются программами, но отличаются от них следующим:

  • Не обеспечивают непосредственной ценности. У конвейера нет пользователей. Конечным потребителям нужны только производимые ими датасеты. Если эти данные попадут в место назначения по какой-то замысловатой схеме перекопирования, то потребителя такой вариант вполне устроит.
  • Имеют для потребителя всего один аспект значимости, а именно создают запрошенный датасет. Следовательно, существует явная точка завершения, хотя сам конвейер требует непрерывного обслуживания ввиду изменений пользовательских требований в вышестоящей системе.
  • Управляют большим количеством состояний. Конвейер предназначен для обработки существующего, не контролируемого им состояния другого ПО и его преобразования в контролируемое. Многие конвейеры выстраивают датасеты поэтапно, с каждым шагом внося в них новые данные. В этом смысле их можно рассматривать как очень долгие процессы, непрерывно создающие всё больше состояний.
  • Неизбежно обладают сильным зацеплением. Цель конвейера состоит в привязке к источнику данных. В итоге его стабильность и надёжность всегда будут зависеть от стабильности и надёжности этого источника.

Эти фундаментальные отличия ставят перед дата-инженерами уникальные вызовы, которые зачастую недостаточно понимают владельцы бизнесов, IT-руководство и даже разработчики ПО.

Далее об этих вызовах мы и поговорим.

Конвейер либо завершён, либо бесполезен


Нынче многие организации управляют своими командами разработчиков ПО с помощью одной из схем Agile. Основная философия этой методологии заключается в максимизации скорости доставки ценности потребителю за счёт создания и релиза элементов ПО в краткосрочных циклах. Задача – максимально быстро поставить клиентам минимально жизнеспособный продукт (MVP) и обеспечить быструю обратную связь, которая бы позволила разработчикам непрерывно трудиться над функционалом, имеющим наивысший приоритет.

Но к инженерии данных эти принципы уже неприменимы.

Конвейер данных нельзя разрабатывать малыми итерациями с возрастающей потребительской ценностью. У конвейера нет MVP-эквивалента — он либо создаёт необходимый потребителю датасет, либо нет.

Следовательно, разработка конвейера данных не вписывается в схемы Agile. Сложный конвейер соответствует одной пользовательской истории, но обычно требует для завершения нескольких спринтов. Руководство, не обладающее технической подготовкой, редко учитывает этот тонкий нюанс и пытается всё равно впихнуть дата-инженеров в scrum команды. В результате пользовательские истории заменяются задачами, например, «создать API-коннектор» и «построить логику потребления», что неизбежно превращает доску Scrum в инструмент микроменеджмента.

Непонимание руководителями основ того, чем они управляют, зачастую ведёт к принятию неэффективных и даже нерабочих решений. Как-то раз разозлённый медленным прогрессом создания конвейера менеджер потребовал от инженера из нашей команды создавать датасет итеративно, столбец за столбцом, чтобы у клиента «были хоть какие-то данные, с которыми можно начать работать». Инженеры, имеющие практический опыт работы со сложными конвейерами, и аналитики данных, которым доводилось получать бесполезный датасет, поймут смехотворность этой ситуации. Для тех же читателей, кто подобного опыта не имеет, приведу три причины, по которым такой подход не сработает:

▍ 1. Ценность частичного датасета не вычисляется пропорционально


Если датасет содержит 9 столбцов из 10, значит ли это, что он полезен на 90%? Всё зависит от того, какого столбца не хватает. Если аналитик собирается построить на основе этих данных предиктивную модель, но отсутствующий столбец представляет метки или прогнозируемые значения, то польза датасета составит 0%. Если же этот столбец содержит какие-то случайные метаданные, не связанные с метками, то такой датасет может оказаться полезен и на все 100%.

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

▍ Время разработки конвейера не соотносится с размером датасета


Даже если клиент будет рад и половине датасета, создание этой половины займёт не вдвое меньше времени, как можно предположить. Конвейер данных состоит не из независимых задач, каждая из которых создавала бы столбец. Несколько столбцов могут быть связаны, если происходят из одного источника, в случае чего включение в конечный датасет хоть одного, хоть нескольких составит одинаковый объём работы.

Однако логика для слияния этих столбцов со столбцами в другой таблице может представлять как простое объединение, так и требовать сложной серии оконных функций. Кроме того, конвейеру для вывода обработанных данных может потребоваться написание большого объёма шаблонного кода, например — клиента для доступа к API или парсера для обработки неструктурированных данных.

После написания такого компонента расширить логику для обработки дополнительных полей будет, скорее всего, несложно. Поэтому количество столбцов в итоговом датасете совершенно не подходит в качестве метрики для оценки его сложности, равно как количество строк написанного кода не подходит для оценки продуктивности.

Размер датасета также может относиться к количеству строк/записей. Грамотно построенный конвейер должен уметь обработать любое число записей, поэтому на времени разработки этот критерий не скажется. Хотя в её процессе могут происходить «скачки», вызванные конкретными условиями вроде:

  • Как часто набор данных нужно обновлять? То есть нужно реализовать пакетное или потоковое обновление?
  • Поступления какого объёма данных мы ожидаем и с какой скоростью?
  • Умещаются ли эти данные в ОЗУ?

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

▍ 3. Затраты времени и ресурсов коррелируют с размером датасета


Чем больше в датасете строк и столбцов, тем больше времени потребуется на его построение и обновление. Редактирование одной записи в огромной базе данных производится легко и быстро, но в датасетах для аналитики такие случаи, как правило, не встречаются. Изменение подобного датасета обычно подразумевает добавление/корректировку целых столбцов (что приводит к изменению всех записей) или обновление тысяч/миллионов строк. Корректировку данных можно обработать двумя способами, ни один из которых не обходится дешёво.

С позиции разработчика изменить датасет проще всего путём обновления конвейера и его повторного выполнения. Однако это оказывается наиболее накладным вариантом в плане вычислительных затрат и времени, необходимого для обновления датасета. Проектирование конвейера так, чтобы он корректно переписывал состояние прошлых выполнений (был идемпотентным) также не всегда оказывается простой задачей и часто требует подобающего предварительного планирования.

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

Как бы то ни было, задача получается сложной, поскольку датасетам свойственна инерция – чем больше их размер, тем больше для внесения изменений требуется времени, усилий и средств.

▍ Вывод: развёртывать частичный конвейер в продакшене бессмысленно


Развёртывание частично готового конвейера в продакшене не принесёт пользы клиенту, зато приведёт к трате вычислительных ресурсов и усложнит жизнь инженеров, поскольку им придётся дополнительно работать со старым состоянием. Слепое привнесение в сферу разработки конвейеров данных принципов DevOps и Agile, где приветствуются постепенные изменения и частые деплои, просто означает игнорирование описанной инерции данных.

Любой инженер предпочёл бы «сделать всё правильно с первого раза» и минимизировать число деплоев в продакшен. Частое развёртывание конвейера говорит либо о том, что клиент не знает чего хочет, либо о том, что источник данных очень нестабилен, и конвейер необходимо постоянно обновлять. В противоположность stateless-приложениям, где обновление по сложности обычно сопоставимо с удалением пары контейнеров и запуском двух новых, обновление датасета не равнозначно повторному развёртыванию кода конвейера. И упаковывание этого кода в контейнер с последующим его запуском в Kubernetes данный пробел не компенсирует.

Циклы обратной связи в разработке конвейеров очень длительны


Для того чтобы быстро создать новый функционал или исправить в ПО баги, разработчикам требуется обратная связь, которая позволит убедиться, что написанный ими код ведёт программу в нужном направлении.

В разработке ПО такая связь обычно достигается посредством модульных тестов, которые программист выполняет локально для проверки правильной работы каждого компонента. Модульные тесты должны быть быстрыми, не связанными ни с какими внешними системами и не зависящими от каких-либо состояний. Они должны тестировать функции, методы и классы независимо. В таком случае программист получает быструю обратную связь во время разработки и может быть уверен, что на момент пул-реквеста его код будет работать должным образом. Если же есть необходимость протестировать взаимодействие с другими системами, конвейер CI также может включать в себя более медленные интеграционные тесты.

Поделюсь секретом дата-инженеров: конвейеры данных редко прогоняют через модульные тесты (сюрприз!). Обычно их тестируют уже посредством развёртывания – как правило, сначала в среде разработки. Для этого требуется этап сборки и деплоя, после которого инженер должен какое-то время помониторить конвейер, убедившись в его правильной работе. Если же конвейер не идемпотентный, то повторный деплой сначала может потребовать ручного вмешательства для сброса состояния, оставленного прежним деплоем. Такой цикл обратной связи очень медленный, если сравнивать его с модульным тестированием.

Так почему бы просто не писать модульные тесты?

▍ 1. Конвейеры данных уязвимы в местах, которые нельзя проверить модульными тестами


Самодостаточная логика, которую можно проверить модульным тестированием, обычно в конвейерах данных ограничена. Бо́льшая часть их кода представляет собой «связующие компоненты и костыли», поэтому почти все сбои возникают в корявых интерфейсах между системами или при попадании в конвейер неожиданных данных.

Интерфейсы между системами нельзя проверить модульными тестами, поскольку изолированно эти тесты не выполняются. Внешние системы можно сымитировать, но это подтвердит лишь правильность работу конвейера с системой, действующей так, как это себе представляет инженер. В реальности же инженер редко знает все детали.

Возьмём пример из жизни: для предотвращения DDOS-атак публичный API может иметь скрытый лимит допустимого числа запросов от одного IP за определённый промежуток времени. Макет такого API вряд ли будет учитывать этот нюанс, но факт его существования в реальной системе может сломать конвейер в продакшене. К тому же внешние системы редко отличаются стабильностью. На деле конвейеры данных обычно создаются, потому что люди хотят переместить данные из неустойчивых систем в более надёжные. Макет же не сможет отразить возможное изменение системы, ведущее к сбою работы конвейера.

При этом хорошо известно, что редко какой поставщик данных сможет предоставлять их постоянно в качественном виде. В конвейере обязательно должно учитываться то, какие ему могут быть переданы данные. Неожиданное содержимое или структура в лучшем случае приведут к неверному результату, а в худшем к сбою его работы. Обычно для защиты от нестабильных источников данных используется проверка схем при считывании.

Но это не оградит от ошибочного содержимого данных и тонких «багов». К примеру, правильно ли во временном ряду учитывается период экономии света? Есть ли в столбце строки, не вписывающиеся в ожидаемый паттерн? Имеют ли физический смысл значения в числовом столбце единиц измерения? Ни один из этих примеров не связан с логикой конвейера, которую можно проверить модульными тестами.

▍ 2. Модульные тесты сложнее логики конвейера


Модульные тесты, необходимые для проверки ограниченной, самостоятельной логики преобразования, сложнее самого кода, поскольку от разработчика требуется создать репрезентативные тестовые данные, а также ожидаемые выходные данные. Это много работы, которая не повысит значительно уверенность в правильном функционировании конвейера. Кроме того, это сменяет вопрос «Работает ли данная функция должным образом?» на «Адекватно ли эти тестовые данные представляют реальные данные?» Модульные тесты идеально охватывают доброе подмножество комбинаций входных параметров, но в функциях, которые преобразуют датасет, к примеру, в датафрейм, сам аргумент датасета представляет чуть ли не бесконечное пространство параметров.

▍ Вывод: конвейеры разрабатываются медленно


Лучший способ получения надёжной обратной связи от конвейера данных – это его развёртывание и запуск. Такой вариант всегда будет медленнее локального выполнения тестов, а значит, для получения обратной связи потребуется намного больше времени. В результате разработка конвейеров, особенно на стадии отладки, движется раздражающе медленно.

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

Сейчас в качестве средства борьбы с ненадёжными поставщиками данных модно использовать «контракты данных». Уверенность в получаемых конвейерами данных исключила бы из процесса разработки значительную долю неуверенности и сделала их менее хрупкими. Однако есть проблема с утверждением таких контрактов, поскольку поставщики данных не заинтересованы следовать утверждаемым ими условиям. Кроме того, организация также захочет использовать данные, полученные из внешних источников вроде публичных API. Можете представить себе ещё и необходимость обсуждения контракта с этими сторонними участниками?

Разработку конвейера невозможно распараллелить


Мы выяснили, что конвейеры данных – это одна пользовательская история, и разрабатываются они медленно ввиду продолжительного цикла обратной связи. Но поскольку конвейер состоит из нескольких задач, некоторые менеджеры в попытке ускорить процесс пытаются распределить их среди нескольких разработчиков.

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

Некоторые менеджеры считают, что это просто означает недостаточную изначальную спланированность конвейера. Есть данные в начале и вполне ясно, какие данные должны получиться в конце. Разве тогда не очевидно, что необходимо выстроить в середине? Парадоксально, но те же менеджеры, которые так рассуждают, будут активно защищать преимущества методов Agile.

Планирование всего конвейера не работает до тех пор, пока источник данных не будет должным образом охарактеризован. При отсутствии контрактов и документации дата-инженер вынужден блуждать в догадках, пытаясь обнаружить частные особенности данных. И этот процесс поиска задаёт архитектуру конвейера. В некотором смысле он получается гибким. Просто такой вариант не устраивает стейкхолдеров.

Общие выводы и рекомендации


Конвейеры данных относятся к программному обеспечению, но не являются программными продуктами. Они представляют собой фабрику, которая лишь собирает запрошенную клиентом машину. Это лишь средства достижения цели, способ автоматизации для создания легко потребляемого датасета на основе громоздких источников данных. Конвейеры – это костыль для связывания систем, в которых не предусмотрено взаимодействие друг с другом. Они являются неуклюжими, хрупкими и дорогостоящими решениями для проблемы «последней мили» в сфере данных. Их единственная задача – управлять состоянием, что делает их разработку медленной, непредсказуемой и зачастую самым узким местом в проектах по аналитике данных.

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

Что же сделать для повышения успешности и продуктивности дата-инженеров?

  • Признать, что лёгкая форма каскадной модели (Waterfall, в разработке ПО обычно считается плохим подходом) в проектах по созданию конвейеров данных неизбежна. Прежде чем начинать разработку, необходимо тщательно проговорить с клиентами требования к нужному им датасету, а также обсудить с поставщиками данных передачу информации о недокументированных API и подключение к системе-источнику. Не тратьте много времени на разработку, пока не достигнете соглашения с клиентами и поставщиками данных. Признайте, что после запуска конвейера в продакшен любые его дальнейшие изменения будут затратны.
  • Позволить дата-инженерам поэкспериментировать с источниками данных. Признать, что все примерные оценки сроков готовности датасета будут ошибочны.
  • Не разделять работу над конвейером между несколькими разработчиками. Вместо этого — позвольте двум или более специалистам трудиться над ним совместно. Максимальной продуктивности позволят добиться техники парного/экстремального/группового программирования в рамках основной ветви, поскольку такой подход исключает неразбериху в git-ветвлении, пул-реквесты и ревью кода. Регулярное инспектирование кода в две пары глаз отлично помогает обнаруживать в нём проблемы, что особенно ценно для конвейеров с очень медленными циклами обратной связи.

Telegram-канал с полезностями и уютный чат

Комментарии (12)


  1. Myclass
    27.11.2022 23:31
    +3

    Ваши слова "Waterfall, в разработке ПО обычно считается плохим подходом."

    Конечно, на просторах этой платформы это обсуждалось уже не раз, но истинной waterfall уже не существует лет 30, а часть её не только здесь нужна - она нужна везде! И при разработке архитектуры софта, и основной модели данных и инфраструктуру без этого не создать. Потом, когда боллее менее всё на ногах стоит, вот тогда можно и на агиль переходить. Но почти всегда забивают многие на такой тщательный подход и потом - и фундамент не выдеживает нагороженное и база данных не может перелопатить правильно и быстро все данные, всё везде тормозит итд.

    Извините, это так походу. За статью же спасибо.


    1. Bright_Translate Автор
      28.11.2022 00:03

      Welcome!


  1. Shatun
    27.11.2022 23:36
    +7

    Конвейер либо завершён, либо бесполезен
    Развёртывание частично готового конвейера в продакшене не принесёт пользы клиенту

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

    пользовательские истории заменяются задачами, например, «создать API-коннектор» и «построить логику потребления», что неизбежно превращает доску Scrum в инструмент микроменеджмента.

    Для меня это отдельные задачи, которые могут делаться разными людьми, причем обычно в параллель. Не понимаю почему это микроменеджмент.

    Разработку конвейера невозможно распараллелить

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

    Любой инженер предпочёл бы «сделать всё правильно с первого раза» и минимизировать число деплоев в продакшен.

    Если процесс деплоя не вызывает боль (например когда много ручных действий или нужно 2 недели собирать аппрувы) то я бы хотел делать деплои как можно чаще.

    Модульные тесты, необходимые для проверки ограниченной, самостоятельной логики преобразования, сложнее самого кода, поскольку от разработчика требуется создать репрезентативные тестовые данные, а также ожидаемые выходные данные. Это много работы, которая не повысит значительно уверенность в правильном функционировании конвейера

    Когда есть пользовательский ввод то вариативность гораздо больше. Но задача тестов не покрыть все возможно варианты входных данных, обычно задача-зафиксировать текущее поведение, чтобы кто-то несломал то что уже работает.


    1. Bright_Translate Автор
      28.11.2022 00:03
      +1

      Спасибо за развернутый, аргументированный комментарий!


  1. Ivan22
    28.11.2022 12:35
    +2

    какой-то сборник мифов.

    Все лень развенчивать, распишу первый: "Конвейер данных нельзя разрабатывать малыми итерациями с возрастающей потребительской ценностью. У конвейера нет MVP-эквивалента — он либо создаёт необходимый потребителю датасет, либо нет. "

    Типичные итерации конвеера с возрастающей ценностью:

    1-я итерация: Делаем простой full load всего сорса в стейджинг, дальше вьюхи на сырых данных - вуаля витрины готовы, минимум времени и уже потребители могут работать с данными

    2-я итерация: Заменяем full load на инкрементальный - скорость загрузки увеличивается в разы, можем быстрее и чаще рефрешить данные - потребительская ценность повышается

    3-я итерация: Добавляем в середину нормализованный слой хранения - появляется внятная модель данных с ключами и ссылочной целостностью, ей удобно пользоваться с помощью adhoc запросов - потребительская ценность повышается

    4-я итерация: Переписываем вьюхи на таблицы или мат.вью - запросы выполняются быстрее - - потребительская ценность повышается

    5-я итерация: Добавляем историчность данных аля scd2 - можно отслеживать историю состояний в прошлом - - потребительская ценность повышается

    И так далее... там и логи и DQ checks и оптимизация стоимости хранения и 100500 других итераций

    Так что:

    Hidden text


    1. Myclass
      28.11.2022 17:32
      +1

      2-я итерация: Заменяем full load на инкрементальный - скорость загрузки увеличивается в разы, можем быстрее и чаще рефрешить данные - потребительская ценность повышается

      И в любой момент времени у вас нормальное состояние для чтения? Вы удаляли когда-нибудь 10 млн. строчек? Или загружали инкрементально 10 млн. строчек? Никто не будет спорить с Вами, что ваш план нереализуем. В каком-то частном случае - конечно-же.

      Но то, что Вы описываете - это больше prototyping - где собирается методом проб и ошибок первый опыт. Но без тщательной продумки архитектуры вам никак. Приведу малюсенький пример - для распределённой бызы данных генератор инкрементального ID не поможет. Надо что-то по-серьёзнее, например GUID - он подходит, но для больших обьёмов может быть по весу чуточку больше, чем хотелось бы итд.

      Ещьё один маленький пример. Вы когда-нибудь изменяли структуру таблицы, когда в ней залито 100 млн. строчек? Если нет - попробуйте и не удивляйтесь, сколько часов ваша таблица не будет ни на какие запросы на чтение отвечать. А в вашем случае - только этим вы и будете заниматься.

      Ваше развенчивание мифов мне напомнило "хер..к, хер.к и в продакшн" и потом с продакшн делать типа что хочешь.И стабильнось ни на грам не изменится! Ага, знаю я такой подход.

      В любом проекте, например и по строительству моста через реку всегда есть фазы, которые надо тщательно продумать, но есть и куча под-заданий, где итеративно можно свою креативность выжимать и не ограничивать себя ничем. Надо только правильно понять, где какие?


      1. Ivan22
        28.11.2022 19:36
        +1

        "Или загружали инкрементально 10 млн. строчек? " еще как загружал. Про структуру кстати тут все продумано, ни в одной из описанных итераций не надо менять структуру фактов наживую.

        p.s. Про генератор инкрементального ID не понял. Видимы вы что-то другое имеете ввиду нежели возможность получать только последние изменные данные из базы источника.

        p.p.s Все вышепреведенное не из пальца высосано, а из собственного опыта, нескольких десятков крупных DWH проектов разного вида, размера, технологий и сфер бизнеса


        1. Myclass
          28.11.2022 20:07
          +1

           Про структуру кстати тут все продумано, ни в одной из описанных итераций не надо менять структуру фактов наживую.

          Ну как не надо?! Если из таблицы с сырыми данными будете делать различные Relations - вы ведь убираете колонку с текстовым значением в таблице, заменяете её на числовую, где новые ИД стоять будут. Потом надо будет ETL-Процесс изменять, потому что в эту таблицу уже оригинальные данные не полезут, а надо будет ключи из других таблиц брать итд. Короче ваше описание не подходит к реальности.

          Многие системы создаются в попыхах, а потом выходит, что нужно паралелльное сохранение и обработка данных или разбиение таблицы на виртуальные партиции итд. Автор правильно указал, что тщательно разработанный концепт архитектуры может стать стабильным фундаментом на года. На коленке собранная и без основательного продумывания - имеет большую вероятность через кое-какое кол-во итераций встать или быть неподходящей или требующей фундаментального редизайна.


          1. Ivan22
            29.11.2022 17:01
            +1

            ведь убираете колонку с текстовым значением в таблице, заменяете её на числовую, где новые ИД стоять будут.

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

            В четвертой итерации заменили вью, на матвью например - но структуру при этом не меняли

            В пятой итерации прикручиваем scd2 к дименшенам ( а не к фактам кстати) ну и опять же - добавить scd2 историчность к таблице не требует её перестройки

            p.s. может вам книгу какую почитать по построению аналитический систем, классику например аля: "The Data Warehouse Toolkit".


        1. Myclass
          28.11.2022 20:44
          +1

           а из собственного опыта, нескольких десятков крупных DWH проектов разного вида, размера, технологий и сфер бизнеса

          ..и что - во всех никогда не задумывались, а сразу выстраивали всю цепочку, а уж только потом доводили моделирование до правильного конца. Не знаю, я в первую очередь оговариваю и обдумываю многие вещи, перед тем, как первые данные вообще поимеют статут - продуктивные. Как будут сохранятся медленные и как например быстрые данные, как история их изменения, нужна-ли она, получаю я её из вне или должен сам делать, или name conventions - при кол-ве 10 таблиц можно их и их поля обзывать по сокращённым, но всё равно по имени, при количестве 25 тысяч - человеческих названий не хватит итд. Без этих и многих других архитектурных продумываний начинать - это курам на смех что получиться.

          Вы отвергаете роль и задачи архитектора, а я наоборот - уверен в том, что без этой роли получиться мало чего хорошего. Это не отменяет, что не имея статуса архитектора вы думаете как архитектор, но ведь эти задачи должны быть кем-то обозначены.


          1. Ivan22
            29.11.2022 17:06
            +1

            Ну например это " как история их изменения, нужна-ли она" в теории круто конечно знать это заранее, а на практике никто из стейкхолдеров потребителей данных не знает на 100% до начала проекта - какая история изменений, как детально и где нужна. Это по-любому итерационный процесс, где в 95% случаев СНАЧАЛА данные начинают использовать, а ПОТОМ понимают нужна ли им история или нет.

            Ну а закладывать историчность во ВСЕ - это оверхед большой, хотя например архитектура Anchor Modeling такое предусматривает, вся история всего, но это слишком специфичная модель и большой оверхед всего, на который идти надо ТОЧНО зная что он нужен, а это опять повторюсь будет известно только ПОСЛЕ выхода в прод и начала полноценной работы с данными


  1. Ivan22
    29.11.2022 17:09

    Вы отвергаете роль и задачи архитектора,

    Ровно наоборот, моя роль как архитектора - заложить модель РАСШИРЯЕМУЮ и гибкую, которую можно расширять и улучшать итерациями, в различных направлениях, в зависимости от потребностей, которые в реальной жизни возникают не ДО начала проекта, а ПОСЛЕ