Pull to refresh

Антихрупкость архитектуры хранилищ данных

Reading time42 min
Views59K
В этой статье речь пойдет об архитектуре хранилищ данных. Чем руководствоваться при ее построении, какие подходы работают – и почему.

«Сказка ложь – да в ней намек…»


imageПосадил дед… хранилище. И выросло хранилище большое-пребольшое. Вот только толком не знал, как оно устроено. И затеял дед ревью. Позвал дед бабку, внучку, кота и мышку на семейный совет. И молвит такую тему: «Выросло у нас хранилище. Данные со всех систем стекаются, таблиц видимо-невидимо. Пользователи отчеты свои стряпают. Вроде бы все хорошо – жить да жить. Да только одна печаль – никто не знает, как оно устроено. Дисков требует видимо-невидимо – не напасешься! А тут еще пользователи ко мне ходить повадились с жалобами разными: то отчет зависает, то данные устаревшие. А то и совсем беда – приходим мы с отчетами к царю-батюшке, а цифры-то между собой не сходятся. Не ровен час – разгневается царь – не сносить тогда головы – ни мне, ни вам. Вот решил я вас собрать и посоветоваться: что делать-то будем?».

Окинул он своим взором собрание и спрашивает:
— Вот ты, бабка знаешь, как оно устроено наше хранилище?
— Нет, дед, не знаю. Да и откуда мне знать-то? Вон там какие бравые хлопцы его охраняют! Одни усищи какие! Не подступишься. Я зашла как-то их проведать, пирожков напекла. А они пирожки-то съели, усы вытерли и говорят: «Да чего ты пришла, бабка? Какое тебе хранилище? Ты скажи – какой тебе отчет нужен – мы тебе и сделаем! Ты главное пирожки почаще приноси! Уж больно они у тебя вкусные.»
— А ты, внученька любимая, знаешь ли как устроено наше хранилище?
— Нет, деда, не знаю. Дали мне как-то доступ к нему. Подключилась я, гляжу — а там таблиц – видимо-невидимо. И в схемы разные упрятаны. Глаза разбегаются…. Я сперва растерялась. А потом пригляделась – какие-то из них пустые, другие заполнены, да лишь наполовину. А еще данные-то, похоже, повторяются. Немудрено, что дисков не напасешься, с такой избыточностью-то!
— Ну а ты, кот, что скажешь про хранилище-то наше? Есть в нем что-то хорошее?
— Да как не сказать, дед – скажу. Я по внучкиной просьбе пытался в отдельной схемке пилотик смастырить – витринку маленькую. Дабы понять, какая торговля для нашего государства выгодна – какие продукты хорошо у купцов идут, те дань платят – казну пополняют. А какие – из рук вон плохо. И стал я из хранилища сего данные себе подбирать. Фактов насобирал. И стал пытаться сопоставить их супротив продуктов. И что же, дед, я увидел – продукты-то они вроде бы и одинаковые, а смотришь в таблички – разные! Принялся я их тогда гребешком внучкиным причесывать. Чесал-чесал – и привел к некому единообразию, глаз ласкающему. Но рано я возрадовался – на другой день запустил я свои скриптики чудесные данные в витринке обновить – а у меня все и разъехалось! «Как так?» — думаю, — внучка-то поди расстроится – сегодня надо было бы наш пилотик министру показывать. Как же мы пойдем-то – с такими данными?
— Да, печальные сказки, кот, рассказываешь. Ну а ты, мышка-норушка, неужто не пыталась разузнать про хранилище? Ты у нас девушка бойкая, юркая, общительная! Что ты нам поведаешь?
— Да как, дедушка, не пытаться – конечно, я мышка тихая, да проворная. Попросила как-то внучка кота модель данных нашего государственного хранилища раздобыть. А кот, конечно, ко мне пришел – на тебя, говорит, мышка, вся надежда! Ну что доброе дело хорошим людям (и котам) не сделать? Пошла я в замок, где начальник хранилища модель данных в сейфе прячет. И затаилась. Дождалась, когда он ту модель из сейфа-то вынет. Только он за кофе вышел – я прыг на стол. Гляжу на модель – ничего понять не могу! Как так? Не узнаю наше хранилище! У нас таблиц тысячи несметные, данных – потоки неуемные! А тут – все стройно да красиво… Посмотрел он на сию модель – и обратно в сейф убрал.
— Да, уж совсем странные вещи, ты нам, мышка, поведала.
Задумался крепко дед.
— Что делать-то будем, други мои? Ведь с таким-то хранилищем долго не проживешь… Пользователи вон скоро – совсем терпение потеряют.
image

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

Разбор полетов


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

Для начала накидаем список типичных проблем, c которыми мы регулярно сталкиваемся, работая с хранилищами. Просто запишем то, что есть – пока без попытки упорядочить и формализовать.
  1. В принципе, у нас неплохое хранилище: если не трогать – то все работает. Правда, как только требуется внести изменение – начинаются «локальные обвалы».
  2. Данные загружаются ежедневно, по регламенту, в рамках одного большого процесса, в течение 8ч. И нас это устраивает. Но если вдруг возникает сбой – это требует ручного вмешательства. И дальше все может работать непредсказуемо долго, т.к. потребуются участие человека в процессе.
  3. Накатили релиз – жди проблем.
  4. Какой-то один источник не смог вовремя отдать данные – ждут все процессы.
  5. Целостность данных контролирует база данных – поэтому наши процессы падают с ошибкой, когда она нарушается.
  6. У нас очень большое хранилище – 2000 таблиц в одной общей схеме. И еще 3000 в множестве других схем. Мы уже слабо представляем, как они устроены и по какому поводу появились. Поэтому, нам бывает сложно что-то переиспользовать. И приходится многие задачи решать заново. Поскольку, так проще и быстрее (чем разбираться «в чужом коде»). В итоге имеем расхождения и дублирующийся функционал.
  7. Мы ожидаем, что источник будет давать качественные данные. Но оказывается, что это не так. В итоге мы много времени тратим на выверку своих финальных отчетов. И весьма в этом преуспели. У нас даже есть отлаженный процесс. Правда, это занимает время. Но пользователи привыкли…
  8. Пользователь не всегда доверяет нашим отчетам и требует обоснования той или иной цифры. В каких-то случаях он прав, а в каких-то нет. Но нам очень сложно их обосновывать, т.к. у нас не предусмотрено средств «сквозного анализа» (или data lineage).
  9. Мы могли бы привлечь дополнительных разработчиков. Но у нас проблема – как нам включить их в работу? Как наиболее эффективно распараллелить работы?
  10. Как развивать систему постепенно, не уходя в разработку «ядра системы» на целый год?
  11. Хранилище данных ассоциируется с корпоративной моделью. Но мы точно знаем (видели в банке XYZ), что строить модель можно бесконечно долго (в банке XYZ шесть месяцев ходили и обсуждали бизнес-сущности, без какого-либо движения). А зачем она вообще? Или может, лучше без нее, если с ней столько проблем? Может, ее вообще как-то сгенерировать?
  12. Мы решили вести модель. Но как системно развивать модель данных хранилища? Нужны ли нам «правила игры» и какие они могут быть? Что нам это даст? А что, если мы ошибемся с моделью?
  13. Должны ли мы сохранять данные, или историю их изменений, если «бизнесу они не нужны»? Не хотелось бы «хранить мусор» и усложнять использование этих данных для реальных задач. Должно ли хранилище сохранят историю? Какая она бывает? Как хранилище работает со временем?
  14. Нужно ли пытаться унифицировать данные на хранилище, если у нас есть система управления НСИ? Если есть МДМ, означает ли это, что теперь вся проблема с мастер-данными решена?
  15. У нас скоро ожидается замена ключевых учетных систем. Должно ли хранилище данных быть готовым к смене источника? Как этого достичь?
  16. Нужны ли нам метаданные? Что под этим будем понимать? Где именно они могут быть использованы? Как можно реализовать? Нужно ли их хранить «в одном месте»?
  17. Наши Заказчики крайне не стабильны в своих требованиях и желаниях – постоянно что-то меняется. У нас вообще бизнес- очень динамичный. Пока мы что-то делаем – это уже становится ненужным. Как нам сделать так, чтобы выдавать результат максимально быстро – как горячие пирожки?
  18. Пользователи требуют оперативности. Но мы не можем наши основные процессы загрузки запускать часто, т.к. это нагружает системы-источники (плохо сказывается на производительности) – поэтому, мы вешаем дополнительные потоки данных – которые будут забирать точечно – то, что нам нужно. Правда, получается много потоков. И часть данных мы потом выкинем. К тому же будет проблема сходимости. Но по-другому никак…

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

Антихрупкость


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

Через какое-то время картина следующая:
«Вот хранилище. И оно работает, если его не трогать. Проблемы возникают тогда, когда мы должны что-то менять».

К нам прилетает изменение, влияние которого мы не в силах оценить и осмыслить (поскольку не заложили таких инструментов в систему изначально) – и дабы не рисковать, мы не трогаем то, что есть, а делаем еще одну пристройку сбоку, и еще одну, и еще — превращая наше решение в трущобы, или как говорят в Латинской Америке, «фавелы», куда даже полицейские заходить боятся.
Возникает ощущение потери контроля над собственной системой, хаоса. Требуется все больше рук, чтобы поддерживать существующие процессы и решать проблемы. И изменения вносить все сложнее. Иными словами, система становится неустойчивой к стрессам, неадаптивной к изменениям. И кроме того, появляется сильная зависимость от персонажей, которые «знают фарватер», поскольку «карты» ни у кого нет.

Такое свойство объекта – разрушаться под воздействием хаоса, случайных событий и потрясений — Нассим Николас Талеб называет хрупкостью. А также вводит противоположное понятие: антихрупкостькогда предмет не разрушается от стресса и случайностей, а получает от него прямую выгоду. («Антихрупкость. Как извлечь выгоду из хаоса»)
Иначе это можно назвать адаптивность или устойчивость к изменениям.

Что это означает в данном контексте? Какие есть «источники хаоса» для ИТ-систем? И что значит «извлечь выгоду из хаоса» с точки зрения ИТ архитектуры?
Первая мысль, которая приходит в голову – изменения, которые приходят извне. Что является внешним миром для системы? Для хранилища в частности. Конечно, прежде всего – изменения со стороны источников данных для хранилища:
  • изменение форматов поступающих данных;
  • замена одних систем-источников данных на другие;
  • изменение правил/платформ интеграции систем;
  • изменение трактовок данных (форматы сохраняются, меняется логика работы с данными);
  • изменение модели данных, если интеграция сделана на уровне данных (разбор журнальных файлов транзакций базы данных);
  • рост объемов данных — пока данных в системе-источнике было немного, и нагрузка была невелика – можно было забирать их когда угодно, сколь угодно тяжелым запросом, данные и нагрузка выросли – теперь есть строгие ограничения;
  • и т.д.
Изменяться могут сами системы-источники, состав информации и ее структура, тип интеграционного взаимодействия, а также сама логика работы с данными. Каждая система реализует свою модель данных и подходы работы с ними, которые отвечают целям и задачам системы. И как бы не стремились унифицировать отраслевые модели и референсные практики – все равно нюансы неизбежно будут всплывать. (Да и к тому же сам процесс отраслевой унификации, по разным причинам не сильно продвигается.)
Культура работы с корпоративными данными – наличие и контроль информационной архитектуры, единая семантическая модель, системы управления мастер-данными (МДМ) несколько облегчают задачу консолидации данных в хранилище, но не исключают ее необходимость.

Не менее критичные изменения инициируются со стороны потребителей хранилища (изменение требований):
  • ранее для построения отчета данных хватало – теперь потребовалось подключить дополнительные поля либо новый источник данных;
  • ранее реализованные методики обработки данных устарели – нужно переработать алгоритмы и все, на что это влияет;
  • ранее всех устраивало текущее значение атрибута справочника на информационной панели – теперь требуется значение, актуальное на момент возникновения анализируемого факта/ события;
  • возникло требование к глубине истории хранения данных, которого раньше не было – хранить данные не за 2 года, а за 10 лет;
  • ранее было достаточно данных по состоянию «на конец дня/ периода» — теперь нужно состояние данных «внутри дня», либо на момент определенного события (например, принятия решения по кредитной заявке – для Basel II);
  • ранее нас устраивала отчетность по данным на вчера (T-1) или позже, сейчас нам нужен T0;
  • и т.д.
И интеграционные взаимодействия с системами-источниками, и требования со стороны потребителей данных хранилища – это внешние факторы для хранилища данных: одни системы-источники сменяют другие, объемы данных растут, форматы поступающих данных меняются, пользовательские требования меняются и т.п. И все это – типовые внешние изменения, к которым наша система – наше хранилище – должно быть готово. При правильной архитектуре они не должны убить систему.

Но это еще не все.
Говоря об изменчивости, мы, прежде всего, вспоминаем внешние факторы. Ведь внутри мы можем все контролировать, нам так кажется, верно? И да, и нет. Да, большинство факторов, которые вне зоны влияния — внешние. Но есть и “внутренняя энтропия”. И именно в силу ее наличия нам иногда нужно вернуться “в точку 0”. Начать игру сначала.
В жизни мы часто склонны начинать с нуля. Почему нам это свойственно? И так ли это плохо?
Применительно к ИТ. Для самой системы – это может оказаться очень хорошо – возможность пересмотреть отдельные решения. Особенно, когда мы можем сделать это локально. Рефакторинг — процесс распутывания той «паутины», которая периодически возникает в процессе развития системы. Возврат «к началу” может быть полезен. Но имеет цену.
При грамотном управлении архитектурой эта цена снижается — и сам процесс развития системы становится более контролируемым и прозрачным. Простой пример: если соблюдается принцип модульности – можно переписать отдельный модуль, не затронув внешние интерфейсы. И этого нельзя сделать при монолитной конструкции.

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

Гораздо более высокую цену будут иметь решения, предполагающие пересмотр всей архитектуры целиком. И для их принятия нужно иметь очень веские основания. Например, таким основанием может служить требование, которое нельзя реализовать в рамках существующей архитектуры. Тогда говорят – появилось требование, влияющее на архитектуру.
Таким образом, мы также должны знать свои «границы антихрупкости». Архитектура не разрабатывается «в вакууме» — она опирается на текущие требования, ожидания. И если ситуация принципиально меняется – мы должны понимать, что вышли за пределы текущей архитектуры – и нам нужно пересмотреть ее, выработать иное решение – и продумать пути перехода.
Например, мы заложились на то, что в хранилище нам нужны будут данные всегда на конец дня, забор данных мы будем делать ежедневно по стандартным интерфейсам систем (через набор представлений). Потом от подразделения управления рисками пришли требования о необходимости получать данные не в конце дня, а на момент принятия решения о кредитовании. Не нужно пытаться «натягивать не натягиваемое» — нужно просто признать этот факт – чем скорее, тем лучше. И начать прорабатывать подход, который позволит нам решить задачу.
Тут возникает весьма тонкая грань – если мы будем принимать во внимание только «требования в моменте» и не будем смотреть на несколько шагов вперед (и на несколько лет вперед), то мы увеличиваем риск столкнуться с влияющим на архитектуру требованием слишком поздно – и цена наших изменений будет очень высока. Смотреть чуть вперед – в границах нашего горизонта – еще никому не вредило.

Пример системы из «сказки про хранилище» — это как раз пример весьма шаткой системы, построенной на хрупких подходах к проектированию. И если так происходит – разрушение наступает довольно быстро, именно для этого класса систем.
Почему я могу так утверждать? Тема хранилищ не нова. Подходы и инженерные практики, которые были за это время выработаны, были направлены именно на это – сохранение жизнеспособности системы.
Простой пример: одна из наиболее частых причин провала проектов хранилищ «на взлете» — это попытка построить хранилище над системами-источниками, находящимися в стадии разработки, без согласования интеграционных интерфейсов – попытка забрать данные напрямую из таблиц. В итоге ушли в разработку – за это время база данных источника поменялась – и потоки загрузки в хранилище стали неработоспособны. Переделывать что-то поздно. А если еще и не подстраховались, сделав несколько слоев таблиц внутри хранилища – то все можно выкинуть и начинать заново. Это лишь один из примеров, причем один из простых.

Критерий хрупкого и антихрупкого по Талебу прост. Главный судья – время. Если система выдерживает проверку временем, и показывает свою «живучесть» и «неубиваемость» — она обладает свойством антихрупкости.
Если при проектировании системы мы будем учитывать антихрупкость как требование – то это сподвигнет нас использовать такие подходы к построению ее архитектуры, которые сделают систему более адаптивной и к «хаосу извне», и к «хаосу изнутри». И в конечном счете система будет иметь более долгий срок жизни.
Никому из нас не хочется делать «времянки». И не надо себя обманывать, что по-другому нынче нельзя. Смотреть на несколько шагов вперед – это нормально для человека в любое время, тем более в кризисное.

Что такое хранилище данных и зачем мы его строим


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

Как вообще люди пришли к тому, что необходимы хранилища данных? И чем они отличаются от просто «очень большой базы данных»?
Давным-давно, когда на свете жили просто «системы обработки бизнес-данных», не было разделения ИТ-систем на такие классы как фронтальные oltp-системы, бэк-офисные dss, системы обработки текстовых данных, хранилища данных и т.д.
Это было то время, когда Майклом Стоунбрейкером была создана первая реляционная СУБД Ingres.
И это было время, когда эра персональных компьютеров вихрем ворвалась в компьютерную индустрию и навсегда перевернула все представления ИТ сообщества того времени.

Тогда можно было легко встретить корпоративные приложения, написанные на базе СУБД класса desktop – таких как Clipper, dBase и FoxPro. А рынок клиент-серверных приложений и СУБД только набирал обороты. Одна за другой появлялись сервера баз данных, которые надолго займут свою нишу в ИТ-пространстве – Oracle, DB2 и т.д.
И был распространен термин «приложение баз данных». Что включало в себя такое приложение? Упрощенно — некие формы ввода, через которые пользователи могли одновременно вводить информацию, некие расчеты, которые запускались «по кнопке» или «по расписанию», а также какие-то отчеты, которые можно было увидеть на экране либо сохранить в виде файлов и отправить на печать.
«Ничего особенного – обычное приложение, только есть база данных,» — так заметил один из моих наставников на раннем этапе трудового пути. «Так ли ничего особенного?» — подумала тогда я.

Если приглядеться – то особенности-то все же есть. По мере роста пользователей, объема поступающей информации, по мере возрастания нагрузки на систему – ее разработчики-проектировщики, чтобы сохранить быстродействие на приемлемом уровне идут на некие «ухищрения». Самое первое – это разделение монолитной «системы обработки бизнес-данных» на приложение учета, которое поддерживает работу пользователей в режиме on-line, и отдельно выделяют приложение для batch-обработки данных и отчетности. Каждое из этих приложений имеет свою базу данных и даже размещается на отдельном экземпляре сервера БД, с разными настройками под разный характер нагрузки – OLTP и DSS. И между ними выстраиваются потоки данных.

Это все? Казалось бы – проблема решена. Что же происходит далее?
А далее компании растут, их информационные потребности множатся. Растет и число взаимодействий с внешним миром. И в итоге есть не одно большое приложение, которое полностью автоматизирует все процессы, а несколько разных, от разных производителей. Число систем, порождающих информацию – систем-источников данных в компании увеличивается. И рано или поздно, возникнет потребность увидеть и сопоставить между собой информацию, полученную из разных систем. Так в компании появляется Хранилища данных – новый класс систем.
Общепринятое определение данного класса систем звучит так.
Хранилище данных (или Data Warehouse) – предметно-ориентированная информационная база данных, специально разработанная и предназначенная для подготовки отчётов и бизнес-анализа с целью поддержки принятия решений в организации
Таким образом, консолидация данных из разных систем, возможность посмотреть на них неким «единым» (унифицированным) образом – это одно из ключевых свойство систем класса хранилищ данных. Это причина, по которой появились хранилища в ходе эволюции ИТ-систем.

Ключевые особенности хранилищ данных


Давайте посмотрим подробнее. Какие ключевые особенности есть у данных систем? Что отличает хранилища данных от прочих ИТ-систем предприятия?

Во-первых, это большие объемы. Очень большие. VLDB – так именуют такие системы ведущие вендоры, когда дают свои рекомендации по использованию своих продуктов. Со всех систем компании данные стекаются в эту большую базу данных и хранятся там «вечно и неизменно», как пишут в учебниках (на практике жизнь оказывается сложнее).

Во-вторых, это исторические данные – “Corporate memory” – так называют хранилища данных. По части работы со временем в хранилищах все совсем интересно. В учетных системах данные актуальные в моменте. Потом пользователь совершает некую операцию – и данные обновляются. При этом история изменений может и не сохраниться – это зависит от практики учета. Возьмем, например, остаток на банковском счете. Нас может интересовать актуальный остаток на «сейчас», на конец дня или на момент некого события (например, в момент расчета скорингового балла). Если первые два решаются довольно просто, то для последнего, скорее всего, потребуется специальные усилия. Пользователь, работая с хранилищем, может обращаться к прошлым периодам, осуществлять их сравнение с текущим и т.д. Именно подобные возможности, связанные со временем, существенным образом отличают хранилища данных от систем учета – получение состояния данных в различных точках оси времени – на определенную глубину в прошлом.

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

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

Архитектурная концепция


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


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

Primary Data Layer — слой первичных данных (или стейджинг, или операционный слой) – предназначен для загрузки из систем-источников и сохранения первичной информации, без трансформаций – в исходном качестве и поддержкой полной истории изменений.
Задача данного слоя – абстрагировать последующие слои хранилища от физического устройства источников данных, способов забора данных и методов выделения дельты изменений.

Core Data Layer — ядро хранилища – центральный компонент системы, который отличает хранилище от просто «платформы batch-интеграции», либо «большой свалки данных», поскольку его основная роль – это консолидация данных из разных источников, приведение к единым структурам, ключам. Именно при загрузке в ядро осуществляется основная работа с качеством данных и общие трансформации, которые могут быть достаточно сложны.
Задача данного слоя – абстрагировать своих потребителей от особенностей логического устройства источников данных и необходимости сопоставлять данные из различных систем, обеспечить целостность и качество данных.

Data Mart Layer — аналитические витрины – компонент, основная функция которого – преобразование данных к структурам, удобным для анализа (если с витринами работает BI – то это, как правило, dimensional model), либо согласно требованиям системы-потребителя.
Как правило, витрины берут данные из ядра – как надежного и выверенного источника – т.е. пользуются сервисом этого компонента по приведению данных к единому виду. Будем называть такие витрины регулярными. В отдельных случаях витрины могут брать данные непосредственно из стейджинга – оперируя первичными данными (в ключах источника). Такой подход, как правило, используется для локальных задач, где не требуется консолидация данных из разных систем и где нужна оперативность более, чем качество данных. Такие витрины называют операционными. Некоторые аналитические показатели могут иметь весьма сложные методики расчетов. Поэтому, для таких нетривиальных расчетов и трансформаций создают так называемые вторичные витрины.
Задача слоя витрин – подготовка данных согласно требований конкретного потребителя – BI-платформы, группы пользователей, либо внешней системы.

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

Также выделяют специальный компонент (или набор компонентов), который оказывает сервисные функции для всех слоев. Одна из ключевых его задач – управляющая функция — обеспечить «единые правила игры» для всей системы в целом, оставляя право на использование различных вариантов реализации каждого из описанных выше слоев – в т.ч. использовать разные технологии загрузки и обработки данных, разные платформы хранения и т.п. Будем называть его сервисным слоем (Service Layer). Он не содержит бизнес-данных, но имеет свои структуры хранения – содержит область метаданных, а также область для работы с качеством данных (и возможно, другие структуры – в зависимости от возложенных на него функций).

Такое четкое разделение системы на отдельные компоненты существенно повышает управляемость развития системы:
  • снижается сложность задачи, которая ставится разработчику функционала того, или иного компонента (он не должен одновременно решать и вопросы интеграции с внешними системами, и продумывать процедуры очистки данных, и думать об оптимальном представлении данных для потребителей) – задачу проще декомпозировать, оценить и выполнить небольшой delivery;
  • можно подключать к работе различных исполнителей (и даже команд, или подрядчиков) – т.к. такой подход позволяет эффективно распараллеливать задачи, снижая их взаимное влияние друг на друга;
  • наличие персистентного стейджинга позволяет быстро подключить источники данных, не проектируя целиком ядро, либо витрины для всей предметной области, а далее постепенно достраивать остальные слои согласно приоритетам (причем данные будут уже в хранилище – доступные системным аналитикам, что существенно облегчит задачи последующего развития хранилища);
  • наличие ядра позволяет всю работу с качеством данных (а также, возможные промахи и ошибки) скрыть от витрин и от конечного пользователя, а главное – используя этот компонент как единый источник данных для витрин, можно избежать проблем со сходимостью данных в силу реализации общих алгоритмов в одном месте;
  • выделение витрин позволяет учесть различия и специфику понимания данных, которые могут быть у пользователей разных подразделений, а их проектирование под требования BI позволяет не только выдавать агрегированные цифры, а обеспечить проверку достоверности данных путем предоставления возможностей drill down до первичных показателей;
  • наличие сервисного слоя позволяет выполнять сквозной анализ данных (data lineage), использовать унифицированные средства аудита данных, общие подходы к выделению дельты изменений, работе с качеством данных, управления загрузкой, средства мониторинга и диагностики ошибок, ускоряет разрешение проблем.

Такой подход к декомпозиции также делает систему более устойчивой к изменением (по сравнению с «монолитной конструкцией») — обеспечивает ее антихрупкость:
  • изменения со стороны систем-источников отрабатываются на стейджинге — в ядре при этом модифицируются только те потоки, на которые оказывают влияние эти стейджинговые таблицы, на витрины влияние минимально либо отсутствует;
  • изменения требований со стороны потребителей отрабатываются по большей части на витринах (если при этом не требуется дополнительная информация, которой еще нет в хранилище).

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

Ядро системы


Начнем «с середины» — ядро системы или средний слой. На схеме обозначен как Core Layer. Ядро выполняет роль консолидации данных — приведение к единым структурам, справочникам, ключам. Здесь осуществляется основная работа с качеством данных – очистка, трансформация, унификация.

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

Модель ядра хранилища и корпоративная модель данных


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

Миф 1. Корпоративная модель данных – это огромная модель, состоящая из тысяч сущностей (таблиц).
На самом деле. В любой предметной области, в любом бизнес-домене, в данных любой компании, даже самой сложной, основных сущностей немного – 20-30.

Миф 2. Не нужно разрабатывать никакую «свою модель» — покупаем отраслевую референсную модель – и делаем все по ней. Тратим деньги – зато получаем гарантированный результат.
На самом деле. Референсные модели действительно могут быть очень полезны, т.к. содержат отраслевой опыт моделирования данной области. Из них можно почерпнуть идеи, подходы, практики именования. Проверить «глубину охвата» области, чтобы не упустить из внимания что-то важное. Но мы вряд ли сможем использовать такую модель «из коробки» — как есть. Это такой же миф, как например – покупка ERP-системы (или CRM) и ее внедрение без какого-либо «докручивания под себя». Ценность таких моделей рождается в их адаптации к реалиям именно этого бизнеса, именно этой компании.

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

Время на разработку модели действительно потребуется. Но это не время, потраченное на «рисование сущностей» — это время, необходимое для анализа предметной области, вникание в то, как устроены данные. Именно поэтому, в этом процессе очень плотно участвуют аналитики, а также привлекаются различные бизнес-эксперты. И делается это точечно, выборочно. А не путем организации встреч с участием безумного количества людей, рассылок огромных анкет и т.п.
Качественный бизнес и системный анализ – вот, что является ключевым при построении модели ядра хранилища. Нужно много чего понять: где (в каких системах) порождаются данные, как они устроены, в каких бизнес-процессах они циркулируют и т.д. Качественный анализ еще ни одной системе не вредил. Скорее, наоборот – проблемы возникают из «белых пятен» в нашем понимании.

Разработка модели данных – это не процесс изобретения и придумывания чего-то нового. Фактически, модель данных в компании уже существует. И процесс ее проектирования скорее похож на «раскопки». Модель аккуратно и тщательно извлекается на свет из «грунта» корпоративных данных и облекается в структурированную форму.

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

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

Миф 6. Если у нас источник данных – это например, система НСИ (или система управления мастер-данными – МДМ), то она уже по-хорошему должна соответствовать корпоративной модели (особенно, если она недавно спроектирована, и не успела обрасти «побочкой», «традициями» и времянками). Выходит, что для этого случая – нам модель ядра не нужна?
На самом деле. Да, в этом случае построение модели ядра хранилище сильно облегчается – т.к. мы следуем готовой концептуальной модели верхнего уровня. Но не исключается вовсе. Почему? Потому что при построении модели определенной системы действуют некие свои правила – какие типы таблиц использовать (для каждой сущности), как версионировать данные, с какой гранулярностью вести историю, какие метаатрибуты (технические поля использовать) и т.п.

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

Слой первичных данных (или историзируемый staging или операционный слой)


На схеме он обозначен как Primary Data Layer. Роль этого компонента: интеграция с системами-источниками, загрузка и хранение первичных данных, а также предварительная очистка данных — проверка на соответствия правилам форматно-логического контроля, зафиксированных в «соглашении об интерфейсе взаимодействия» с источником.
Кроме того, данный компонент решает очень важную для хранилища задачу – выделения «истинной дельты изменений» — не зависимо от того, позволяет ли источник отслеживать изменения в данных или нет и каким образом (по какому критерию их можно «поймать»). Как только данные попали в стейджинг – для всех остальных слоев вопрос выделения дельты уже понятен – благодаря маркировке мета-атрибутами.

Данные в этом слое хранятся в структурах, максимально близких к системе-источнику – чтобы сохранить первичные данные как можно ближе к их первозданному виду. Еще одно название этого компонента — «операционный слой».
Почему бы просто не использовать устоявшийся термин “staging”? Дело в том, что ранее, до «эпохи больших данных и VLDB», дисковое пространство было очень дорого – и часто первичные данные если и сохранялись, то ограниченный интервал времени. И часто именем “staging” называют очищаемый буфер.
Теперь же технологии шагнули вперед – и мы можем позволить себе не только хранить все первичные данные, но историзировать их с той степенью гранулярности, которая только возможна. Это не означает, что мы не должны контролировать рост данных и не отменяет необходимость управлять жизненным циклом информации, оптимизируя стоимость хранения данных, в зависимости от «температуры» использования – т.е. уводя «холодные данные», которые менее востребованы, на более дешевые носители и платформы хранения.

Что нам дает наличие «историзируемого стейджинга»:
  • возможность ошибиться (в структурах, в алгоритмах трансформации, в гранулярности ведения истории) – имея полностью историзируемые первичные данные в зоне доступности для хранилища, мы всегда можем сделать перезагрузку наших таблиц;
  • возможность подумать – мы можем не торопиться с проработкой большого фрагмента ядра именно в этой итерации развития хранилища, т.к. в нашем стейджинге в любом случае будут, причем с ровным временным горизонтом (точка «отсчета истории» будет одна);
  • возможность анализа – мы сохраним даже те данные, которых уже нет в источнике – они могли там затереться, уехать в архив и т.д. – у нас же они остаются доступными для анализа;
  • возможность информационного аудита – благодаря максимально подробной первичной информации мы сможем потом разбираться – как у нас работала загрузка, что мы в итоге получили такие цифры (для этого нужно еще иметь маркировку мета-атрибутами и соответствующие метаданные, по которым работает загрузка – это решается на сервисном слое).

Какие могут возникнуть сложности при построении «историзируемого стейджинга»:
  • было бы удобно выставить требования к транзакционной целостности этого слоя, но практика показывает, что это трудно достижимо (это означает то, что в этой области мы не гарантируем ссылочную целостность родительских и дочерних таблиц) – выравнивание целостности происходит на последующих слоях;
  • данный слой содержит очень большие объемы (самый объемный на хранилище — несмотря на всю избыточность аналитических структур) – и надо уметь обращаться с такими объемами – как с точки зрения загрузки, так и с точки зрения запросов (иначе можно серьезно деградировать производительность всего хранилища).

Что еще интересного можно сказать про этот слой.
Во-первых, если мы отходим от парадигмы «сквозных процессов загрузки» — то для нас больше не работает правило «караван идет со скоростью последнего верблюда», точнее мы отказываемся от принципа «каравана» и переходим на принцип «конвейера»: взял данные из источника – положил в свой слой – готов брать следующую порцию. Это означает, что
1) мы не ждем, пока случиться обработка на других слоях;
2) мы не зависим от графика предоставления данных другими системами.
Проще говоря, мы ставим на расписание процесс загрузки, который берет данные из одного источника через определенный способ подключения к нему, проверяет, выделяет дельту – и помещает данные в целевые таблицы стейджинга. И все.

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

Слой аналитических витрин


Слой Витрин (Data Mart Layer на схеме) отвечает за подготовку и предоставление данных конечным потребителям – людям или системам. На этом уровне максимально учитываются требования потребителя – как логические (понятийные), так и физические. Сервис должен предоставлять ровно то, что необходимо – не больше, не меньше.

Если потребителем является внешняя система, то как правило, она диктует те структуры данных, которые ей необходимы и регламенты забора информации. Хорошим подходом считается такой, при котором за корректный забор данных отвечает сам потребитель. Хранилище данные подготовило, сформировало витрину, обеспечило возможность инкрементального забора данных (маркировка мета-атрибутами для последующего выделения дельты изменений), а система-потребитель далее сама управляет и отвечает за то, как она этой витриной пользуется. Но бывают особенности: когда система не имеет активного компонента для забора данных – нужен либо внешний компонент, который выполнит интегрирующую функцию, либо хранилище выступит в роли «платформы интеграции» — и обеспечит корректную инкрементальную отгрузку данных далее – за пределы хранилища. Здесь всплывает много нюансов, и правила интерфейсного взаимодействия должны быть продуманы и понятны обеим сторонам (впрочем, как всегда – когда дело касается интеграции). К подобным витринам, как правило, применяется регламентное очищение/ архивирование данных (редко нужно, чтобы эти «транзитные данные» хранились длительное время).

Наибольшее значение с точки зрения аналитических задач представляют собой витрины «для людей» — точнее для инструментов BI, с которыми они работают.
Впрочем, есть категория «особо продвинутых пользователей» — аналитики, исследователи данных — которым не нужны ни BI-инструменты, ни регламентные процессы наполнения внешних специализированных систем. Им требуются некие «общие витрины» и «своя песочница», где они могут создавать таблицы и трансформации по своему усмотрению. В этом случае ответственность хранилища заключается в обеспечении наполнения данными этих общих витрин в соответствие с регламентом.
Отдельно можно выделить таких потребителей как средства Data Mining – глубокого анализа данных. Такие инструменты имеют свои требования к преподготовке данных, и с ними также работают эксперты по исследованию данных. Для хранилища задача сводится – опять же к поддержке сервиса по загрузке неких витрин согласованного формата.

Однако, вернемся к аналитическим витринам. Именно они представляют собой интерес с точки зрения разработчиков-проектировщиков хранилища в этом слое данных.
На мой взгляд, лучший подход к проектированию витрин данных, проверенный временем, на который сейчас «заточены» практически все платформы BI – это подход Ральфа Кимбалла. Он известен под названием dimensional modeling – многомерное моделирование. Существует великое множество публикаций на эту тему. Например, с основными правилами можно ознакомиться в публикации Марги Росс. И конечно же, можно рекомендовать книгу-бестселлер от гуру многомерного моделирования. Другой полезный ресурс – «Советы Кимбалла»
Многомерный подход к созданию витрин описан и проработан столь хорошо – как со стороны «евангелистов метода», так и со стороны ведущих вендоров ПО, что нет смысла здесь как-то подробно на нем останавливаться – первоисточник всегда предпочтительнее.

Хотелось бы сделать лишь один акцент. «Отчетность и аналитика» бывает разной. Есть «тяжелый reporting» — предзаказанные отчеты, которые формируются в виде файлов и доставляются пользователям по предусмотренным каналам доставки. А есть информационные панели – BI dashboards. По своей сути это web-приложения. И к времени отклика этих приложений предъявляются такие же требования, как и для любого другого web-приложения. Это означает, что нормальное время обновления BI-панели – это секунды, а не минуты. Важно это помнить при разработке решения. Как этого достичь? Стандартный метод оптимизации: смотрим, из чего складывается время отклика и на что мы можем влиять. На что больше всего тратиться время? На физические (дисковые) чтения БД, на передачу данных по сети. Как уменьшить объем считываемых и передаваемых данных за один запрос? Ответ очевиден и прост: нужно данные либо агрегировать, либо наложить фильтр на большие таблицы фактовые таблицы, участвующие в запросе, и исключить соединение больших таблиц (обращения к фактовым таблицам должны идти только через измерения).

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

Не всегда достаточно просто построить «правильную звезду» — и получить удобную структуру для BI. Иногда потребуется где-то применить денормализацию (оглядываясь при этом, как это повлияет на загрузку), а где-то сделать вторичные витрины и агрегаты. Где-то добавить индексы или проекции (в зависимости от СУБД).

Таким образом, путем “проб и ошибок” можно получить структуру, оптимальную для BI – которая учтет особенности как СУБД, так и BI-платформы, а также требования пользователя по представлению данных.
Если мы данные мы берем из «ядра», то такая переработка витрин будет носить локальный характер, никак не влияя на сложную обработку первичных данных, полученных непосредственно из систем-источников – мы лишь «перекладываем» данные в удобный для BI формат. И можем себе позволить сделать это множество раз, различными способами, в соответствие с различными требованиями. На данных ядра делать это гораздо проще и быстрее, чем собирать из «первички» (структура и правила которой, как мы знаем, к тому же может «поплыть»).

Сервисный слой


Сервисный слой (на схеме — Service Layer) отвечает за реализацию общих (сервисных) функций, которые могут использоваться для обработки данных в различных слоях хранилища – управление загрузкой, управление качеством данных, диагностика проблем и средства мониторинга и т.п.
Наличие данного уровня обеспечивает прозрачность и структурированность потоков данных в хранилище.

К этому слою относят две области хранения данных:
  • область метаданных – используется для механизма управления загрузкой данных;
  • область качества данных – для реализации офф-лайн проверок качества данных (т.е. тех, что не встроены непосредственно в ETL-процессы).

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

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

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

Не ставлю задачу здесь полностью осветить эту тему – организации загрузки – лишь расставляю акценты, на которые стоит обратить внимание.
Приведенный подход – это лишь один из вариантов. Он довольно адаптивен. И его «концептуальным прототипом» послужил конвейер Toyota и система «точно во время» (just-in-time). Т.е. мы здесь отходим от широко распространенной парадигмы исключительно «ночной загрузки данных», а загружаем небольшими порциями в течение дня – по мере готовности данных в различных источниках: что пришло – то и загрузили. При этом у нас работают множество параллельных процессов. А «горячий хвост» свежих данных будет постоянно «моргать» — и через какое-то время выравниваться. Мы должны учесть такую особенность. И в случае необходимости формировать пользовательские витринами «срезами», где все уже целостно. Т.е. нельзя одновременно достичь и оперативности, и консистентности (целостности). Нужен баланс – где-то важно одно, где-то другое.

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

Проектирование и ведение моделей данных хранилища


Почему при разработке любой системы, где задействована база данных (а в хранилище – особенно), важно уделять внимание проектированию моделей данных? Почему бы просто не накидать набор таблиц, где угодно – хоть в текстовом редакторе? Зачем нам «эти картинки»?
Как ни странно, подобные вопросы ставят даже опытные разработчики.
Вообще-то да, ничто не мешает набросать таблицы — и начать их использовать. Если… если при этом в голове (!) у разработчика есть стройная общая картина той структуры, которую он ваяет. А что, если разработчиков несколько? А что, если эти таблицы будет использовать кто-то еще? А что если пройдет время – человек оставит эту область, а потом к ней опять вернется?

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

А самое главное даже не это. Самое главное, что при проектировании модели мы вынуждены (просто без вариантов!) более плотно и глубоко изучить предметную область, особенности устройства данных и их использования в различных бизнес-кейсах. И те вопросы, которые бы мы с легкостью «отодвинули» как сложные, «замылили», накидывая наши таблички, не пытаясь при этом именно проектировать модель — мы будем вынуждены поставить и решать сейчас, при анализе и проектировании, а не потом – когда будем строить отчеты и думать о том, «как свести несовместимое» и каждый раз «изобретать велосипед».

Такой подход является одной из тех инженерных практик, которые позволяют создавать антихрупкие системы. Поскольку они понятно устроены, прозрачны, удобны для развития, а также сразу видны их «границы хрупкости» — можно более точно оценить «масштабы бедствия» при появлении новых требований и время, необходимое для редизайна (если он понадобится).
Таким образом, модель данных – один из основных артефактов, который должен поддерживаться в процессе развития системы. По-хорошему, она должна быть «на столе» у каждого аналитика, разработчика и т.д. – всех, кто участвует в проектах развития системы.

Проектирование моделей данных – это отдельная, весьма обширная тема. При проектировании хранилищ используются два основных подхода.
Для ядра хорошо подходит подход «сущность-связь» — когда строится нормализованная (3NF) модель на основе именно исследования предметной области, точнее выделенной ее области. Здесь играет та самая «корпоративная модель», о которой шла речь выше.

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

Далее очень просто перейти к физической модели, добавив элементы оптимизации с учетом особенностей СУБД. Например, для Oracle это будет секционирование, набор индексов и т.д. Для Vertica будут использованы другие приемы – сортировка, сегментация, секционирование.
Также может потребоваться специальная денормализация — когда мы сознательно вносим избыточность в данные, благодаря которым улучшаем быстродействие запросов, но при этом усложняем обновление данных (т.к. избыточность нужно будет учитывать и поддерживать в процессе загрузки данных). Возможно, в целях улучшения быстродействия, нам также придется создать дополнительные таблицы-агрегаты, либо использовать такие дополнительные возможности СУБД как проекции в Vertica.

И далее над такой структурой довольно просто настроить инструменты BI, посредством которых конечный пользователь будет видеть и анализировать данные.

Итак, при моделировании данных хранилища мы фактически решаем несколько задач:
  • задача построение концептуальной (логической) модели ядра — системный и бизнес анализ — исследование предметной области, углубление в детали и учет нюансов «живых данных» и их использования в бизнесе;
  • задача построения модели анализа – и далее концептуальной (логической) модели витрин;
  • задача построения физических моделей – управление избыточностью данных, оптимизация с учетом особенностей СУБД под запросы и загрузку данных.

При разработке концептуальных моделей, мы можем не учитывать особенности конкретной СУБД, для которой мы проектируем структуру БД. Более того, мы можем использовать одну концептуальную модель для создания нескольких физических – под разные СУБД.

Резюмируем.
  • Модель данных – это не набор «красивых картинок», а процесс ее проектирования – это не процесс их рисования. Модель отражает наше понимание предметной области. А процесс ее составления – это процесс ее изучения и исследования. Вот на это тратится время. А вовсе не на то, чтобы «нарисовать и раскрасить».
  • Модель данных – это проектный артефакт, способ обмена информацией в структурированном виде между участниками команды. Для этого она должна быть всем понятна (это обеспечивается нотацией и пояснением) и доступна (опубликована).
  • Модель данных не создается единожды и замораживается, а создается и развивается в процессе развития системы. Мы сами задаем правила ее развития. И можем их менять, если видим – как сделать лучше, проще, эффективнее.
  • Модель данных (физическая) позволяет консолидировать и использовать набор лучших практик, направленных на оптимизацию – т.е. использовать те приемы, которые уже сработали для данной СУБД.

Особенности проектов хранилищ данных


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

Хранилище данных – это заказное ПО


Хранилище данных – это всегда «заказная разработка», а не коробочное решение. Да, существуют отраслевые BI-приложения, включающие в себя референсную модель данных, преднастроенные ETL-процессы из распространенных источников (например, ERP систем), набор типовых панелей BI и отчетов. Но на практике хранилище крайне редко внедряется – как «коробка». Я работаю с хранилищами около 10 лет, и ни разу не видела такой истории. Всегда всплывают свои нюансы, связанные с уникальными особенностями компании – как бизнеса, так и ИТ-ландшафта. Поэтому, надеяться, что архитектуру предоставит «вендор», поставляющий решение несколько опрометчиво. Архитектура таких систем часто «вызревает» внутри самой организации. Либо ее формируют специалисты компании-подрядчика, являющегося основным исполнителем по проекту.

Хранилище данных – это интеграционный проект


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

Хранилище данных – это коллективный проект


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

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

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

Хранилище данных имеет более длительный срок жизни по сравнению с другими системами


Уточню – утверждение справедливо для «живого», работающего хранилища, интегрированного с ключевыми источниками, обладающего историческими данными и обеспечивающего информационно-аналитическими сервисами многие подразделения компании.

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

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

Постепенное итеративное развитие


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

Хранилище данных в глазах Заказчиков зачастую выглядит абсолютным монстром – настолько объемны задачи, цели и горизонт развития системы. И часто Заказчик боится, что «за счет его бюджета» ИТ-подразделение будет решат какие-то «свои задачи». И снова мы сталкиваемся с вопросом взаимодействия между людьми и умения спокойно излагать свою позицию и договариваться.

Грамотные архитектурные подходы позволяют развивать систему итеративно, наращивая функционал постепенно, не уходя в «разработку» на несколько лет, прежде чем начинать давать результат.

Хотя надо отметить, что «чудес не бывает» — и на «старт» тоже нужно время. Для хранилищ оно бывает достаточно велико – поскольку это большие объемы данных, это исторические данные – за старые периоды, когда правила обработки информации могли отличаться от нынешних. Поэтому, требуется достаточно времени на аналитическую проработку, взаимодействие с системами-источниками и ряд «проб и ошибок», включая нагрузочные тесты на реальных данных.

Хранилища данных – «мульти-проектная история»


Для хранилища данных сложно выделить единственного бизнес-заказчика. И считается (не без оснований), что ключевым фактором успешности проекта построения хранилища является поддержка руководства компании – непосредственно первого лица.
Хранилище редко строится и развивается в рамках одного проекта. Как правило, есть различные потребности в консолидации данных и аналитике, за ними стоят разные Заказчики и группы пользователей. Поэтому, хранилище часто развивается в рамках нескольких параллельно идущих проектов.

Баланс инноваций и проверенных решений


Несмотря на то, что тема хранилищ – очень «древняя» (если такое слово применимо для такой молодой отрасли как ИТ) и достаточно консервативна. Тем не менее, прогресс не стоит на месте – и те ограничения, которые ранее существовали в силу дорогих и медленных дисков, дорогой памяти и т.п. – теперь сняты. А вместе с тем, пришла пора пересмотреть некоторые архитектурные подходы. Причем это относится как к технологическим платформам, так и к архитектуре прикладных систем, которые на них базируются.
image Тут важно соблюсти баланс – и сохранить достаточно «экологичный» подход как к ресурсам, так и к хранимой информации. Иначе можно очень быстро превратить хранилище в слабоструктурированную «помойку», в которой если и можно будет разобраться, то путем довольно больших усилий.
Да, у нас появилось больше возможностей, но это не значит, что нужно отрицать все наработанные и проверенные временем практики, которые понятно как и зачем использовать, и «пускаться во все тяжкие» лишь ведомые туманным призраком «инноваций».
Соблюдать баланс – значит использовать новые методы и подходы там, где они открывают новые возможности, но вместе с тем использовать старые проверенные – для решения насущных задач, которые никто не отменял.
Что можем сделать мы как разработчики и проектировщики прикладных решений? Прежде всего, знать и понимать технологические изменения платформ, на которых мы работаем, их возможности, особенности и границы применения.

Посмотрим на СУБД – как наиболее критичную и важную для хранилищ технологическую платформу.
Последнее время явно наметился дрейф реляционных баз данных, созданных изначально как «универсальных», в сторону специализации. Уже давно ведущие вендоры выпускают различные опции – для приложений разного класса (OLTP, DSS & DWH). Кроме того, появляются дополнительные возможности для работы с текстом, гео-данными и т.д.

Но этим дело не ограничилось — стали появляться продукты, которые изначально ориентированы на определенный класс задач – т.е. специализированные СУБД. Они могут использовать реляционную модель, а могут и нет. Важно то, что они изначально «заточены» не просто на хранение и обработку «бизнес информации» в целом, а под определенные задачи.

Видимо, централизация и специализация – это два взаимодополняющих тренда, которые периодически сменяют друг друга, обеспечивая развитие и баланс. Также как и эволюционное (постепенное) постепенное развитие и кардинальные перемены. Так, в 90-х годах Майкл Стоунбрейкер был одним из авторов Манифеста баз данных III поколения, в котором четко звучала мысль, что миру не нужна еще одна революция в мире баз данных. Однако спустя 10 лет он публикует работы, в которых анонсирует предпосылки начала новой эры в мире СУБД – именно исходя из их специализации.
Он акцентирует внимание на том, что распространенные универсальные СУБД построены на «безразмерной» (one-size-fits-all) архитектуре, которая не учитывает ни изменений аппаратных платформ, ни разделения приложений на классы, для которых можно придумать более оптимальное решение, нежели реализуя универсальные требования.
И начинает развивать ряд проектов в соответствие с этой идеей. Один из которых – C-Store – колоночная СУБД, спроектированная в архитектуре shared nothing (SN), изначально созданная специально для систем класса хранилищ данных. Далее этот продукт получил коммерческое развитие как HP Vertica.

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

Эпилог


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

По большом счету, не важно – кто именно выполняет роль архитектора – важно, что кто-то ставит подобные вопросы и исследует на них ответы. Если архитектор явно выделен – это лишь означает, что ответственность за систему и ее развитие несет, прежде всего, он.
Почему мне показалась тема «антихрупкости» релевантной относительно данного предмета?

Отвечу словами непосредственно автора концепции:
“Уникальность антихрупкости состоит в том, что она позволяет нам работать с неизвестностью, делать что-то в условиях, когда мы не понимаем, что именно делаем, – и добиваться успеха” /Нассим Н.Талеб/
Поэтому, кризис и высокая степень неопределенности – это не оправдание в пользу отсутствия архитектуры, а факторы, усиливающие ее необходимость.
Tags:
Hubs:
+17
Comments15

Articles