В рамках продвижения нашего нового курса по графовой аналитике больших данных в бизнес-приложениях, сегодня разберем сложности рефакторинга графовых моделей в Neo4j и способы их обхода с помощью библиотеки APOC и плагина Liquibase. Что такое Liquibase и как Data Scientist и аналитик данных могут использовать его совместно с Neo4j.
Гибкость модели данных и трудности рефакторинга в Neo4j
С одной стороны, гибкая модель данных дает разработчику широкие возможности, позволяя манипулировать различными типами данных. С другой стороны, такая гибкость чревата ошибками и несовместимостью типов. В частности, необязательность схемы NoSQL-СУБД Neo4j удобна для быстрого прототипирования, но может превратиться в настоящий кошмар, если разработчик не будет постоянно контролировать сложность данных по мере их роста. К примеру, при импорте данных извне их необходимо преобразовать в графы после первоначальной загрузки. Например, склеить некоторые узлы графа воедино, присоединив новые данные к существующим узлам. Но сделать это не так-то просто из-за отсутствия четко заданной схемы.
Для решения подобных проблем существуют специальные инструменты, например, Liquibase, которые обеспечивают высокоуровневый рефакторинг базы данных. Liquibase — это решение для управления изменениями схемы базы данных с открытым исходным кодом, которое позволяет управлять версиями изменений, позволяя:
- устранять ошибки и задержки при обновлении и релизе базы данных;
- развертывать и откатывать изменения для определенных версий;
- внедрять синхронные изменения базы данных вместе с приложениями.
Для Neo4j есть плагин Liquibase, который позволяет отслеживать, версионировать и выполнять изменения этой графовой базы данных, а также выполнять рефакторинг — реструктуризацию кода без изменения его наблюдаемого поведения. Вообще рефакторинг в Neo4j выполняется с помощью библиотеки APOC (Awesome Procedures on Cypher), которая, помимо всего прочего, также включает пакет apoc.refactor. Эта библиотека считается самым большим и наиболее часто используемой модулем расширений для Neo4j. Он включает более 450 стандартных процедур, предоставляющих функциональные возможности для утилит, преобразований, обновления графов и пр. Все эти компоненты легко запускать как отдельные функции или включать в запросы Cypher. Поэтому перед разработкой собственной UDF для графовой аналитики больших данных рекомендуется сначала проверить наличие готовой функции в библиотеке APOC. Подробно об истории появления и возможностях этой мощной библиотеки мы писали в прошлой статье.
Для рефакторинга в API библиотеки APOC есть серверные расширения и функция склейки узлов mergeNodes, которые имеют прямой доступ к серверному Java API Neo4j. Этот Java API предоставляет доступ к постоянным объектам отношений (Relationship) и узлов (Node), которые можно модифицировать перед программной фиксацией окружающей транзакции.
Однако, на стороне клиента, т.е. на стороне драйвера Neo4j, единственный способ изменить данные — это выполнить запросы встроенного SQL-подобного языка запросов Cypher. Поэтому для постоянных объектов Node и Relationship рекомендуется предоставить пользователю возможность указать шаблон Cypher, описывающий объединяемые узлы. Так можно использовать этот шаблон в более крупном запросе Cypher и получить последовательность узлов для слияния. Но это сводится к процедуре конкатенации строк Cypher и является небезопасным из-за возможности атак типа SQL-инъекция, когда в строку запроса вплетается вредоносный код. Как плагин Liquibase решает эту проблему обновления модели данных Neo4j, мы рассмотрим далее.
Как работает Liquibase
Плагин Liquibase обходит проблему внедрения вредоносного кода в строку запроса, позволяя пользователям выполнять произвольные изменения с требуемыми разрешениями. Благодаря полному контролю запускаемых операторов, атаки SQL/Cypher-инъекций не представляют угрозы с Liquibase.
Но, если операция слияния выполняется внутри одной транзакции, возможна другая проблема, связанная с нехваткой памяти. При работе с большим количеством данных, чем может обработать сервер, транзакция будет прервана. В этом случае рекомендуется разделять узлы для слияния по разным пакетам. Но так слияние перестает быть транзакцией – серией операций, которая либо выполняется полностью либо не выполняется вообще.
Liquibase не поддерживает пакетное выполнение, т.к. исторически разрабатывалась для реляционных баз данных, рефакторинг которых означает изменение их структуры с помощью DDL-операторов. Эти операторы языка SQL обычно требуют меньше памяти, чем их DML-аналоги, кроме добавления нового столбца со значением по умолчанию, отличным от NULL, в таблицу с огромным количеством строк. Но в случае с Neo4j различий между DDL и DML на самом деле нет: модель выводится из данных, а данные — это и есть модель. Поэтому DDL-подобные операции в Neo4j часто подвержены проблемам масштабируемости. Читайте в нашей новой статье про тонкости некоторых Cypher-запросов в этой графовой базе данных.
Освойте администрирование и эксплуатацию Neo4j и Apache Spark для графовой аналитики больших данных на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:
Источники