11
0
0
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники
Назад

Автоматический линеаж витрин данных

Время чтения 9 минут
Нет времени читать?
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники
11
0
0
Нет времени читать?
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники

Приветствую специалистов по данным!

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

Автоматический линеаж витрин данных

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

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

Это решение приятно тем, что а) связи выстраиваются автоматически (неручная документация); б) можно выбрать любую конкретную таблицу и увидеть компактные метаданные о ней. Однако минусы так же очевидны, как и плюсы:

  • нет графического представления связей, только табличное;
  • возможно видеть только первый уровень «потомков» и «предков», более далекие уровни недоступны.

Постановка задачи

Попробуем сформулировать требования смелее и полнее, чем в прошлой «итерации»:

  • Пара «представление + кеш-таблица» рассматривается как единый объект — витрина данных. Имя представления = префикс v_ + имя кеш-таблицы.
  • Для исследуемой витрины должны выводиться все ее «предки» всех уровней до самого начала и все «потомки» до конца. Кроме того, нужна возможность регулировать количество выводимых уровней.
  • Связи должны быть представлены в виде графа, в котором узлы — это таблицы и представления, а стрелки между ними — направленные связи.
  • Должна быть возможность посмотреть метаданные любого объекта (схемы, описания и т. д.).
  • Отображение должно быть интерактивным, то есть обеспечивать возможность изменения масштаба, перемещения узлов для удобства, вывода свойств выделенного объекта.

Решение

Требования у нас суровые, но нам не нужно изобретать велосипед. Ведь существуют специальные графовые СУБД, заточенные как раз под нашу задачу! Популярный их представитель — Neo4j, его-то мы и будем использовать для отрисовки нашего линеажного графа.

Предположим, наши витрины лежат в ClickHouse, стало быть, нам нужно «соединить» эти две СУБД. Именно поэтому решение состоит из следующих шагов:

  1. Разворачиваем Neo4j.
  2. Создаем таблицу всех связей между витринами, используя уже известный нам механизм обращения к system.tables.
  3. Экспортируем эту структуру из ClickHouse в Neo4j.
  4. Работаем с линеажным графом в Neo4j через интерфейс в обычном браузере. В этой СУБД используется свой язык запросов — Cypher. С его помощью можно выбрать исследуемую витрину, задать количество уровней и т. д.

Разберем эти шаги подробнее.

Установка Neo4j

Для тестовой итерации ставить Neo4j будем на локальную Linux-машину. Позже можно перенести на удаленную, чтобы доступ к линеажу имела вся команда.

Для развертывания Neo4j воспользуемся Docker. Выполняем команды:


sudo systemctl restart docker
docker run -d 
  --name neo4j 
  -p 7474:7474 
  -p 7687:7687 
  -e NEO4J_AUTH=neo4j/your_password 
  neo4j:latest

 

Если не вылезло ошибок, то открываем браузер по адресу http://localhost:7474 и видим приглашение ко входу в СУБД:

Вводим логин и пароль, указанные при установке, и видим интерфейс Neo4j:

Верхнее текстовое поле neo4j$ предназначено для ввода cypher-запросов.

Но база пока пуста. Перейдем к загрузке в нее структуры наших таблиц.

Передача структуры таблиц из ClickHouse в Neo4j

Скрипт, формирующий структуру связей между объектами в ClickHouse и отправляющий эти данные в Neo4j, можно скачать из репозитория. Основной его функционал описывается двумя классами:

1. ClickHouseLineageExtractor — извлечение из ClickHouse данных об объектах и их связях. Класс включает функции: 

  • __init__ — создание клиента для обращения к ClickHouse (библиотека clickhouse_driver);
  • get_tables — извлечение метаданных обо всех таблицах и представлениях всех несистемных баз;
  • get_columns — извлечение метаданных о полях этих объектов;
  • get_dependencies — формирование зависимостей (связей) между объектами.

2. Neo4jLineageLoader — загрузка данных в Neo4j. Класс включает в себя методы:

  • __init__ — создание клиента для обращения к Neo4j (библиотека neo4j);
  • run_query — запуск запросов в Neo4j;
  • load_schemas — загрузка схем, таблиц;
  • load_tables — загрузка списка таблиц с их свойствами;
  • load_columns — загрузка узлов колонок (да, у полей в нашем графе будут собственные узлы, привязанные к узлам соответствующих таблиц);
  • load_dependencies — загрузка связей.

Этот скрипт можно запускать разово при необходимости либо поставить на расписание через любой оркестратор или шедулер. Любые изменения структуры таблиц в ClickHouse сразу отразятся в его system.tables, а значит, их подхватит скрипт. Далее данные в Neo4j будут перезаписаны обновленными.

Результат

После того как Neo4j благополучно установился, а скрипт экспорта структуры отработал, в браузере по адресу http://localhost:7474, залогинившись, мы можем запускать cypher-запросы. Например, запрос


  MATCH path = (ancestor:Table)-[:FEEDS_INTO*]->(t:Table {name: 'accounts'})
  RETURN path

 

покажет в виде графа всех «предков» витрины accounts:

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

Вот некоторые другие запросы на языке Cypher:


  // Ближайшие «родители» (1-й уровень)
  MATCH (parent:Table)-[:FEEDS_INTO]->(t:Table {name: 'report_accounting_sa_money'})
  RETURN parent, t
 
  // Все «потомки» таблицы (lineage вниз)
  MATCH path = (t:Table {name: 'my_table'})-[:FEEDS_INTO*]->(descendant:Table)
  RETURN path
 
  // Полный lineage (вверх и вниз)
  MATCH path = (a:Table)-[:FEEDS_INTO*]-(t:Table {name: 'money'})
  RETURN path
 
  // Все таблицы схемы
  MATCH (t:Table)-[:BELONGS_TO]->(s:Schema {name: 'datamart'})
  RETURN t
 
  // Таблицы без «родителей» (источники данных)
  MATCH (t:Table)
  WHERE NOT ()-[:FEEDS_INTO]->(t)
  AND t.schema = 'datamart'
  RETURN t
 
  // Колонки таблицы
  MATCH (t:Table {name: 'money'})-[:HAS_COLUMN]->(c:Column)
  RETURN c ORDER BY c.position

 

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

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

Резюме

Линеаж витрин данных в виде наглядного интерактивного графа можно реализовать путем экспорта структуры объектов и связей между ними из аналитического хранилища в графовую СУБД. Мы рассмотрели скрипт, который выгружает модель данных из ClickHouse и загружает в Neo4j.

Работать с графом в Neo4j можно, запуская типовые cypher-запросы и управляя полученным графом в пользовательском интерфейсе прямо в браузере.

Такая визуализация значительно упрощает и ускоряет исследование модели данных.

Комментарии0
Тоже интересно
Комментировать
Поделиться
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники