我目前正在开发一个使用JDK1.7编译的项目,使用Cascading 1.2(即将升级到2.1)创建并运行Hadoop作业,并使用Hadoop的Cloudera发行版(0.20.2-cdh3u3)。
我正在研究如何修改我的Cascading / Hadoop作业以读取和写入MySQL数据库的所有数据。看起来SQOOP可能能够解决这个问题。
然而,从我到目前为止所看到的,关于如何在Java中执行此操作的信息或文档很少(我知道SQOOP主要用于从shell中调用的批处理作业) - 我有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。)
答案 0 :(得分:2)
Sqoop用于在MySQL /其他关系数据库和Hadoop / HBase之间导出/导入数据。可以找到关于sqoop的非常好的教程here,它解释了它的各种功能。不确定这是否是你想要做的。
如果您需要在MapReduce作业中从/向MySQL读取/写入数据,可以按照@Charles的建议使用DBInputFormat/DBOutput
hadoop类
答案 1 :(得分:1)
如果您只想将作业输出写入MySQL,我建议使用here所述的名为DBOutputFormat
的其他输出格式:
伴侣类DBOutputFormat将允许您将结果写回数据库。设置作业时,请调用conf.setOutputFormat(DBOutputFormat.class);然后像以前一样调用DBConfiguration.configureDB()。
然后,DBOutputFormat.setOutput()方法定义如何将结果写回数据库。它的三个参数是作业的JobConf对象,一个定义要写入的表名称的字符串,以及一个字符串数组,用于定义要填充的表的字段。例如,DBOutputFormat.setOutput(job,“employees”,“employee_id”,“name”);.
您之前创建的相同DBWritable实现足以将记录注入数据库。将在从reducer传递给OutputCollector的DBWritable的每个实例上调用write(PreparedStatement stmt)方法。在还原结束时,那些PreparedStatement对象将转换为INSERT语句以对SQL数据库运行。
“如前所述”指的是这条指令:
DBConfiguration.configureDB(conf, “com.mysql.jdbc.Driver”, “jdbc:mysql://localhost/mydatabase”);
要从MySQL读取它与DBInputFormat
完全相同。
答案 2 :(得分:1)
感谢Charles和Vikas。这当然让我走上正轨。我最终使用https://github.com/cwensel/cascading.jdbc使用Hadoop类DBInputFormat/DBOutput
来轻松设置读写db的Cascading作业。
要写,我只是将我的点击输出流程更改为:
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,但似乎这只是从db中读取而不是写入它们。