Можно ли использовать SQOOP из Java для чтения / записи из MySQL в / из заданий Hadoop?

В настоящее время я работаю над проектом, который компилируется с использованием JDK1.7, создает и запускает задания Hadoop с использованием Cascading 1.2 (скоро будет обновлен до 2.1) и использует дистрибутив Cloudera для Hadoop (0.20.2-cdh3u3).

Я смотрю, как изменить мои задания Cascading / Hadoop для чтения и записи всех данных в / из базы данных MySQL. Похоже, что SQOOP сможет с этим справиться.

Однако из того, что я видел до сих пор, мало информации или документации о том, как это сделать на Java (я понимаю, что SQOOP в основном предполагается использовать для пакетных заданий, вызываемых из оболочки) - примеры Java, за которыми я следил, убежище ' у меня сработало. Я попытался использовать SQOOP 1.4 и переключить свой проект на использование JDK1.6, поскольку я считаю, что это необходимо (хотя это нарушит другие части моего проекта), но я все еще не мог заставить его работать.

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

Когда я пытаюсь запустить org.apache.sqoop.tool.ExportTool для экспорта CSV в таблицу, возникают следующие ошибки:

Не удается инициализировать процессор javac из-за (скорее всего) проблемы с загрузчиком классов: java.lang.NoClassDefFoundError: com / sun / tools / javac / processing / JavacProcessingEnvironment

Примечание. \ Tmp \ sqoop-my.name \ compile \ 9031edc8e43167c10f9f895b64aa79d5 \ MyTableName.java использует или переопределяет устаревший API.

Обнаружено исключение IOException при выполнении задания экспорта: java.io.IOException: не удалось загрузить файл jar \ tmp \ sqoop-my.name \ compile \ 9031edc8e43167c10f9f895b64aa79d5 \ MyTableName.jar в JVM. (Не удалось найти класс MyTableName.)


person hello-klol    schedule 06.06.2013    source источник


Ответы (3)


Sqoop предназначен для экспорта / импорта данных между MySQL / другими реляционными базами данных и Hadoop / HBase. Очень хорошее руководство по sqoop можно найти здесь, в котором объясняются его различные функции. . Не уверен, что ты хочешь этим заниматься.

Если вам нужно читать / записывать данные из / в MySQL в заданиях MapReduce, можно использовать DBInputFormat/DBOutput классы hadoop, как это было предложено @Charles

person VikasG    schedule 06.06.2013

Если вы просто хотите записать вывод задания в MySQL, я бы рекомендовал использовать другой формат вывода, называемый DBOutputFormat, как описано здесь:

Сопутствующий класс DBOutputFormat позволит вам записывать результаты обратно в базу данных. При настройке задания вызовите conf.setOutputFormat (DBOutputFormat.class); а затем вызовите DBConfiguration.configureDB (), как раньше.

Затем метод DBOutputFormat.setOutput () определяет, как результаты будут записаны обратно в базу данных. Его три аргумента - это объект JobConf для задания, строка, определяющая имя таблицы для записи, и массив строк, определяющий поля таблицы для заполнения. например, DBOutputFormat.setOutput (работа, сотрудники, employee_id, name) ;.

Та же реализация DBWritable, которую вы создали ранее, будет достаточной для вставки записей обратно в базу данных. Метод write (PreparedStatement stmt) будет вызываться для каждого экземпляра DBWritable, который вы передаете в OutputCollector из редуктора. В конце сокращения эти объекты PreparedStatement будут преобразованы в операторы INSERT для работы с базой данных SQL.

Где, как и раньше, относится к этой инструкции:

DBConfiguration.configureDB(conf, “com.mysql.jdbc.Driver”, “jdbc:mysql://localhost/mydatabase”);

Для чтения из MySQL все равно с DBInputFormat.

person Charles Menguy    schedule 06.06.2013

Спасибо, Чарльз и Викас. Это, безусловно, поставило меня на верный путь. В итоге я использовал https://github.com/cwensel/cascading.jdbc, который использует классы Hadoop. DBInputFormat/DBOutput, чтобы упростить настройку каскадных заданий, которые читают и записывают в базу данных.

Чтобы написать, я просто изменил выходной поток моего крана на:

String url = "jdbc:mysql://localhost:3306/mydb?user=myusername&password=mypassword";
String driver = "com.mysql.jdbc.Driver";
String tableName = "mytable";   
String[] columnNames = {'col1', 'col2', 'col3'}; //Columns I want to write to 
TableDesc tableDesc = new TableDesc( tableName );

JDBCScheme dbScheme = new JDBCScheme( columnNames );
Tap dbOutputTap = new JDBCTap( url, driver, tableDesc, dbScheme );

И чтобы читать из базы данных, я просто сделал тап, который выглядел так:

String url = "jdbc:mysql://localhost:3306/mydb?user=myusername&password=mypassword";
String driver = "com.mysql.jdbc.Driver";
String tableName = "mytable";      
String[] columnNames = {'col1', 'col2', 'col3'}; //Columns I want to read from 
TableDesc tableDesc = new TableDesc( tableName );

JDBCScheme dbScheme = new JDBCScheme( columnNames, "col1<40" );
Tap dbInputTap = new JDBCTap( url, driver, tableDesc, dbScheme );

Я также столкнулся с Cascading-DBMigrate, но, похоже, это только для чтения из базы данных, а не для записи в них.

person hello-klol    schedule 17.06.2013