Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Введение
Часто перед дата-инженерами ставится задача по миграции данных из какого-либо источника или системы в целевое хранилище. Для этого существует множество различных инструментов. Если говорить про платформу Big Data, то чаще всего у разработчиков на слуху Apache NiFi или ETL-задачи, написанные на Spark, ввиду универсальности этих инструментов. Но давайте предположим, что нам необходимо провести миграцию данных из РСУБД в Hadoop. Для подобного рода задач существует очень недооцененный пакетный ETL-инструмент – Apache Sqoop. Его особенность в следующем:
- Облегчает работу разработчиков, предоставляя интерфейс командной строки. Для работы с этим инструментом достаточно заполнить основную информацию: источник, место назначения и детали аутентификации базы данных;
- Автоматизирует большую часть процесса;
- Использует инфраструктуру MapReduce для импорта и экспорта данных, что обеспечивает параллельный механизм и отказоустойчивость;
- Для работы с этим инструментом требуется иметь базовые знания компьютерной технологии и терминологии, опыт работы с СУБД, с интерфейсами командной строки (например bash), а также знать, что такое Hadoop и обладать знаниями по его эксплуатации;
- Относительно простая установка и настройка инструмента на кластере.
Выглядит любопытно? Но что на счёт вышеупомянутой задачи по миграции данных? Давайте разбираться.
Возможности инструмента Apache Sqoop
Перед тем как начать работу с любым новым инструментом, необходимо иметь хотя бы общее понимание о том, как этот инструмент устроен. Для этого рекомендую ознакомиться с архитектурой Apache Sqoop, которая изображена на рисунке 1:
Рисунок 1 – Архитектура Apache Sqoop
Поясним детально:
Client Command – исполняемая команда оболочки. Команда попадает в Task Translator, который преобразует её в соответствующую задачу MapReduce. Далее происходит обмен данными между РСУБД и Hadoop, где в качестве узла взаимодействия между двумя системами выступает Java DataBase Connectivity (JDBC). В качестве приемника информации могут использоваться Hive, HBase и непосредственно HDFS.
Стоит отметить, что миграция данных между РСУБД и Hadoop может проводиться в обе стороны – иными словами Apache Sqoop поддерживает не только операции импорта, но и экспорта данных.
Вернёмся к нашей задаче. Apache Sqoop позволяет выяснить – какие базы данных подняты на сервере (
--list-databases
) и какие таблицы доступны пользователю для импорта (--list-tables
). Эти удобные функции могут пригодиться в том случае, когда нет чёткого понимания откуда и что именно требуется загрузить, а также нет возможности получить детализацию о доступных базах и таблицах соответствующими запросами к БД из любой клиентской среды. Обладая всей необходимой информацией об источнике, можно приступать к миграции данных.Для того, чтобы запустить задачу импорта, необходимо указать набор минимальных обязательных параметров. К ним относятся параметры подключения к источнику, параметры, описывающие источник данных, и параметры целевого хранилища:
- --connect – содержит в себе строку подключения JDBC. Строка может содержать прямой адрес до сервера базы данных с указанием хоста, порта и прочих параметров. Или эту информацию можно передать в JDBC в виде TNS;
- --username – имя подключаемой пользователя базы данных;
- --password – пароль пользователя базы данных. Также пароль может передаваться в строку импорта не в чистом виде, а быть зашифрован или храниться в текстовом файле. Для этой операции шифрования используется CredentialProvider API (ссылка на документацию в разделе «Источники»);
- --table – имя читаемой таблицы;
- --query – SQL запрос в –том случае, если читаемая таблица импортируется из источника в целевое хранилище не 1 к 1 и необходима агрегация данных и/или фильтрация данных;
- --target-dir – целевая директория хранения импортируемых данных. Однако если в своей задаче вы используете импорт данных непосредственно в Hive, после завершения задачи данные переместятся в Hive Warehouse;
- --driver – опционально – в зависимости от конфигурации кластера и версии Sqoop потребуется указать драйвер подключения.
Таким образом получаем следующую процедуру импорта (в качестве примера используется подключение к тестовой базе PostgeSQL):
Sqoop import --connect 'jdbc:postgresql://datalike-node2.do.neoflex.ru:5432/teneo' --username postgres --password redacted --driver org.postgresql.Driver --table rt_oozie --delete-target-dir --target-dir /user/admin/sqoop_example/
В процессе выполнения задачи импорта в консоль выводятся логи её работы. В случае успешного завершения процесса получаем детальную информацию о том, сколько данных и в каком объёме было загружено. Пример изображен на рисунке 2.
Рисунок 2 – Лог загрузки данных Sqoop задачи
Далее поговорим о простых вещах, которые существенно расширяют функциональные возможности Apache Sqoop. Не будем повторять техническую документацию, поэтому ограничимся описанием функций без конкретизации параметров. User Guide доступен по ссылке ниже в разделе «Источники» в конце статьи (на момент написания статьи актуальная версия 1.4.7).
В некоторых случаях возникает необходимость в миграции не всей таблицы целиком из РСУБД, а лишь некоторого набора полей этой сущности с дополнительными условиями фильтрации или агрегацией. Для таких ситуаций применим параметр
--query
, который используется вместо параметра --table
и содержит в себе SQL запрос. Еще одно из возможных применений запроса вместо указания таблицы – это отсутствие поля на источнике, по которому необходимо сделать партицирование в Hadoop. На практике довольно часто в исходных данных встречаются поля типа «Timestamp», при этом это единственное поле, содержащее дату. В подобных ситуациях приходится вводить дополнительное поле с датой (вычисленной из поля с типа «Timestamp») и уже по нему проводить партицирование данных. Также отмечу, что описывать сложную логику трансформации данных можно, но делать этого не следует. Инструмент предназначен скорее для миграции данных, нежели для их трансформации и выгрузки «налету».В нашем примере не указан формат данных. По умолчанию Sqoop производит выгрузку в текстовом формате с разделителем полей «запятая» и разделителем строки «\n» (новая строка). В случае если такой вариант не устраивает, разделители всегда можно изменить. Кроме текстового формата выгрузку можно проводить в следующие форматы: avro, sequencefile, parquet, а также ORC и RCFile (но только при сохранении в Hive и автоматическом создании таблицы при записи данных). Чаще всего на практике применяется parquet. Также можно применить различные доступные для конкретного формата кодеки сжатия. По умолчанию используется GZIP, но кроме него доступны Snappy и BZIP. При сохранении в формат AVRO не стоит забывать, что кодек GZIP им не поддерживается.
Apache Sqoop также поддерживает загрузку в Hive, HBase и Amazon S3 (более подробно узнать о работе Sqoop с Amazon S3 можно по ссылке в разделе «Источники»). При этом вовсе не обязательно наличие целевых таблиц в системе. При указании дополнительных опций задача импорта создаст их автоматически, самостоятельно определив и скорректировав типы полей. Если потребуется, типы полей при создании таблицы можно переопределить специальными параметрами.
В Apache Sqoop предусмотрены параметры, позволяющие использовать инструмент для массового импорта данных. Однако есть ограничения – всего три режима:
- Импорт одной таблицы;
- Импорт всех таблиц;
- Импорт всех таблиц, исключая таблицы из списка.
Ограничение заключается в отсутствии встроенного функционала импорта таблиц из списка. С другой стороны, эту ситуацию можно решить как минимум двумя способами:
1. Так как задачу импорта можно запускать в интерпретаторе командной строки (к примеру, bash), процесс последовательного импорта по одной таблице можно также автоматизировать, описав в конфигурационном файле набор необходимых сущностей для импорта;
2. Если имеется возможность создавать/менять объекты в DB, то можно ограничить область видимости. Например, создать пользователя, для которого написаны public synonyms только те таблицы, которые нужно импортировать. Тогда формально, выполняя импорт всех таблиц, можно выгрузить только необходимые сущности.
Эти два варианта помогут решить поставленную задачу, но на наш взгляд, использовать Sqoop в этом случае не совсем практично.
Как уже говорилось ранее, Apache Sqoop поддерживает параллельный импорт данных (в рамках миграции одной таблицы). Для этого необходимо указать поле, по которому произойдет деление данных между мапперами и количество мапперов (параллельных потоков). Однако тут есть одна очень неприятная особенность: значение поля, по которому идёт деление данных между потоками, должно равномерно возрастать. В идеале это должен быть первичный ключ сущности, который, кстати, используется по умолчанию в качестве разделителя при импорте. Объясняется эта необходимость очень просто – при разделении задачи между мапперами, используется условие типа «between». Соответственно, если значение поля возрастает неравномерно, может возникнуть ситуация, при которой одному мапперу условно достанется на импорт 100 строк, другому – 10 000.
Инструмент поддерживает два режима загрузки данных – перезапись и добавление. Для обоих в Apache Sqoop существуют свои параметры. Перезапись реализована простым удалением целевой директории, а вот с добавлением всё куда интереснее, особенно если рассматривать процедуру добавления данных к уже существующим с точки зрения загрузки дельты данных. Реализовано это следующим образом: в параметрах указывается колонка и её последнее значение, которое было ранее загружено в хранилище. По факту при выборке данных будет выполняться запрос с условием вида
where table_field > *last_value*
. Но это еще не всё. В случае, если скомпилировать строку импорта в Sqoop задачу (saved job), параметр --last-value
будет обновляться автоматически, анализируя и подставляя в задачу последние значения столбца. Итоги
Apache Sqoop – это узконаправленный инструмент, который фактически разрабатывался и был нацелен исключительно на взаимодействие РСУБД и Hadoop. Безусловно, в статье представлен не весь функционал инструмента, а лишь описаны наиболее востребованные вещи в типовых задачах. Что же касается области применений инструмента, можно сказать следующее: его однозначно можно и нужно использовать, когда есть необходимость срочно и быстро загрузить объект из РСУБД в Hadoop – как говорилось ранее, у Sqoop высокая производительность, которая достигается за счет возможности параллелить задачу импорта. Он также подойдет в случае, если отсутствует экспертиза по работе с другими ETL-инструментам, так как для работы с Apache Sqoop достаточно уметь пользоваться терминалом и знать некоторые консольные команды. Если объектов на регулярную выгрузку не очень много, Apache Sqoop также можно использовать как целевой ETL-инструмент, так как он неплохо работает в связке с планировщиками задач Apache Oozie или Apache AirFlow.
В каких случаях, возможно, не следует применять инструмент:
Во-первых, если объектов на миграцию достаточно много и все они находятся в разных системах, например, MySQL, Oracle, FoxPro, Sybase, IBM Domino Server и др. В таком случае следует прибегнуть к более универсальному ETL-средству.
Во-вторых, это дело вкуса – некоторым разработчикам ближе Spark и для них предпочтительнее, быстрее провести тот же самый импорт, не используя сторонние инструменты.
Выводы
Apache Sqoop отлично подходит для решения небольших и срочных задач по миграции данных из РСУБД. Очень легок в освоении, что позволяет быстро адаптироваться и начать разработку импорта, не имея глубокой экспертизы в области технологий Big Data. Однако, для решения масштабных вопросов в части миграции данных, следует воспользоваться более универсальными инструментами для «тонкой» настройки функционала.
Источники
1 CredentialProvider API Guide– Электрон. дан. – Режим доступа: hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/CredentialProviderAPI.html.
2 Sqoop User Guide – Электрон. дан. – Режим доступа: sqoop.apache.org/docs/1.4.7/SqoopUserGuide.html.
3 Importing Data into Amazon S3 Using Sqoop – Электрон. дан. – Режим доступа: docs.cloudera.com/documentation/enterprise/latest/topics/admin_sqoop_s3_import.html