Привет! Меня зовут Никита Хилов, я работаю в билайне уже более десяти лет. Начинал я работать с поддержкой систем фиксированного фиксированного биллинга, впоследствии я отвечал за разработку и поддержку различных расчетов по системам управленческой или корпоративной отчетности. А сейчас я работаю в роли тимлида дата-инженеров в блоке по архитектуре и инфраструктуре данных и отвечаю за управление разработкой и сопровождением программных продуктов компании по различным точкам бизнес-приложения.
Итак, какие же вопросы мы обсудим в этой серии постов. Сегодня я хочу осветить вопросы касаемо того, как же нам организовывать, компоновать и в принципе заставить работу систему журналирования наших расчетов для таких случаев, когда наш общепринятый ключ периодики, на котором мы обычно строим свои расчеты, перестает быть однозначным идентификатором той итерации процесса подготовки данных, на которую мы сейчас смотрим, и от которых мы ждем результаты.
Мы обсудим, например, когда такое происходит и что для этого является катализатором. Рассмотрим механики и механизмы, которые дают возможность связывать независимые процессы и цепочки подготовки данных в единое целое.
И в дополнение расскажу, как мы эту проблему решали в своем продукте.
Но прежде всего давайте определим для чего нам это, в принципе, нужно. При проектировании проработки сценариев отчетности, это может быть управленческая, бухгалтерская, финансовая, корпоративная, критично учитывать основные требования, которые к ней будут предъявлены.
Требования для отчётности
Для бухотчетности и финансовой отчетности есть даже специальные законы и нормы, которые эти требования отражают. Но если расширить круг, то какие же требования будут предъявляться, например, к внутренней отчётности компании?
Прежде всего, отчетность, которая предоставляется разработчиками и владельцами отчетов вовне, то есть в инфраструктуру самой компании, должна быть достоверна и надежна. Другими словами, это отчетность должна отражать реальное положение дел в компании. Также отчетность должна быть оперативной, и в данном случае под оперативностью отчетности занимается то, что она должна предоставляться к такому сроку, пока она является необходима для принятия решений.
Также отчетность должна быть доступной и полезной. Информацию в этой отчетности будут считать полезной при выполнении условий, что она является уместной, надежной, сравнимой и своевременной.
А ещё отчетность должна быть понятной. Сведения, которые предоставляются в отчете, должны быть в понятном пользователю виде, тогда эти документы можно правильно трактовать и правильно понимать.
И отчетность должна быть полной. В данном случае суть этого требования состоит в предоставлении всей необходимой отчетной информации. Так, большинство этих требований находятся явно в зоне ответственности владельца того или иного продукта или того или иного отчета. Сложно требовать от разработчика на том же Spark знаний по основам бухучета. Но эти требования должны быть проработаны на этапе архитектуры, на этапах системного бизнес -анализа и при этом не потеряны при переходе к разработке и сопровождению.
Что же это фактически значит для дата-инженера, который проектирует свое программное решение поставленной задачи?
В ходе своей работы мы должны исходить из необходимости удовлетворения как минимум двух двух основополагающих требований, которые будут впоследствии владельцами уже наложены на наши отчеты. Это требование гарантирования актуальности данных и требование гарантирования качества этих данных.
Формализовать второе требование о качестве данных, в принципе, достаточно сложно, но давайте будем исходить из того, что мы должны строить свои отчеты, исходя хотя бы из трех критериев:
Наши отчеты должны строиться на достоверных, поддерживаемых и обновляемых источниках.
Мы должны в рамках разработки и запусков налагать на алгоритмы и структуры данных, которые мы при этом используем, все определяемые нашим производственным процессом тесты.
Мы должны записывать в систему журналирования или логирования достаточную информацию, которая может быть необходимой при решений различных конфликтов.
Однако, как можно гарантировать актуальность данных? Как ее можно проверить и измерить?
Вот сейчас и узнаем.
Для начала важно поднять и ответить самим себе на вопрос.
Какие у нас данные?
Если мы заглянем под капот информационных систем, то мы увидим, что в большинстве из них данные организованы в таблице фактов и таблице измерений.
Что такое таблица фактов? Таблица фактов является основной таблицей хранилища данных. Как правило, она содержит сведения об объектах или событиях, совокупность которых мы потом планируем в принципе дальнейшем анализировать.
Какие же это могут быть факты? Выделяют, как правило, четыре группы основополагающих фактов.
Первый факт — это факты, которые связаны с транзакциями. Они основываются на отдельных событиях. Например, телефонный звонок или снятие денег со счета с помощью банкомата.
Вторая группа фактов связана с моментальными снимками. Они основываются на состоянии объекта, например, банковского счета, в определенные моменты времени. Это может быть время на конец дня, либо в конце месяца. Типичными такими примерами будут объемы продаж за сутки или дневная выручка.
Третий же тип фактов — это факты, связанные с элементами документов. Они основаны, как правило, на том или ином документе. Это может быть счет за услуги, счет за товар, какие-то счета-фактуры и подобное. Они содержат в себе подробную информацию об элементах этого документа, там может быть количество товара, его цена, проценты скидки
Четвертая группа — это факты, которые связаны с событием или состоянием объекта, но при этом они предоставляют только сам факт возникновения или, наоборот, отсутствия того или иного события, не предоставляя при этом никаких особых подробностей.
При этом эти факты зачастую группируют по значениям какого-либо заранее выбранного ключа, и правило это даты совершения фактов. Сохраняют их в раздельные места для ускорения доступа к тому или иному набору фактов. Каждый такой отдельный набор формирует партиции или секции.
Итак, с таблицей фактов понятно, но что тогда у нас относится к таблице измерений?
Информация в таблице измерений в структуре базы данных содержит атрибуты событий, которые мы сохранили в таблице фактов. Атрибуты могут представлять собой текстовые или иные описания, логически объединенные в одно целое. Например, имя покупателя будет атрибутом в таблице измерения покупателей, наименование товара, соответственно, в таблице измерения товара. В то же время, как сумма транзакций является величиной аддитивной, её значение таким образом должно храниться в таблице фактов.
Давайте предположим, что мы имеем некоторый набор данных, отражающий информацию о продаже книг. У нас есть идентификаторы книги, автора категории и любой сопутствующий факт продажи набор атрибутов. Однако есть один очень важный атрибут, который превращает наш набор данных из обычного перечисления в набор фактов. Это атрибут времени совершения факта продажи. И важен атрибут в этом контексте еще и тем, что именно время является ключевым элементом системы гарантирования актуальности данных.
Вернемся к таблице фактов.
Предположим, что перед нами поставили задачу составить иерархию жанров, например, по суммам выплаченных комиссий за отчетный период. У нас есть информация о продажах, есть ссылки на авторов, их проценты комиссий и информация, подтверждающая, что тот или иной платеж автору был выполнен.
В нашем отчете мы получаем список продаж за отчетный период с суммами соответствующих транзакций. По ключу автора мы находим для каждой продажи размер процента выплат. Перед нахождением итоговой суммы вознаграждения убираем те, что еще не были совершены. Итоговый результат мы сложили в слой витрин в таблицу нашего отчета и отправляем в уведомление о готовности потребителям или рассылаем этот отчет по заказчикам.
Что будет, если мы попробуем наложить ранее обсужденные два требования на эту модель расчета? На какой же вопрос мы прежде всего должны ответить?
Вопрос этот будет звучать так — как происходит обновление данных в наших отчетных периодах? Ведь формально у нас существуют три варианта обновления наших данных, к ним относятся полная, инкрементная и дифференциальная загрузка.
Первый вариант предполагает свое использование в системах, которые как правило поддерживают вендор, когда среды аналитики и разработки выносят в отдельные информационные единицы для исключения нагрузки с аналитиков или разработчиков на продуктивные контура.
Второй и третий вариант, то есть инкрементальная и дифференциальная загрузка, представляет собой уже приближенные к в реальному жизненному циклу в операции, в компании и ее процессам. Для лучшего понимания давайте проведем аналогию с бэкапированием. Как и в наших моделях обновления данных, у систем резервного копирования выделяют три схожих вида. Это полный бэкап, дифференциальный бэкап и инкрементальный бэкап.
Полный бэкап осуществляет сохранение полной копии нашей системы или тех данных, которые мы отметили к резервному копированию. И каждый такой снимок в нашем хранилище при полном резервном копировании с заданной периодичностью начинает создавать архивы, где данные в основной своей массе дублируются. Это его серьезный и ключевой недостаток, ведь расходуется огромный объем ресурсов и места в хранилище, время создания и время процессорное, вычислительные мощности.
Поэтому есть ещё и такие варианты, как инкрементальный вид резервного копирования, которое является более экономичным и более быстрым, чем полный бэкап, поскольку в процессе инкрементального копирования будут создаваться только такие файлы, которые изменились со времени предыдущего резервного копирования, которое могло быть либо полным бэкапом, либо другой итерацией нашего инкрементального копирования. Исходные же данные, которые не изменились и которые мы изначально сохранили, они не перезаписываются.
Дифференциальный же бэкап обрабатывает файлы, измененные или созданные с момента выполнения предыдущего полного бэкапа. Однако, вне зависимости от той модели обновления данных в нашем наборе фактов, изменения в секцию могут в реальности прийти как полностью за секцию, например, продажи книг за день, когда мы секцию формируем по дню, но и могут инкрементно, по мере появления их в системах источников, например, при потоковом формате загрузки данных.И в большинстве случаев поведение данных будет определяться жизненным циклом компании. И в этот момент у нас появляется разный подход для разной модели обновления, что мы и обсудим в продолжении этого поста.