是否可以在java中使用sqoop从mysql读写hadoop作业?

bvhaajcl  于 2021-06-04  发布在  Hadoop
关注(0)|答案(3)|浏览(417)

我目前正在从事一个项目,该项目使用jdk1.7进行编译,使用级联1.2(即将升级到2.1)创建和运行hadoop作业,并使用hadoop的cloudera发行版(0.20.2-cdh3u3)。
我正在研究如何修改级联/hadoop作业,以便在mysql数据库中读写所有数据。看起来sqoop可以处理这个问题。
然而,据我所见,关于如何在java中实现这一点的信息或文档很少(我知道sqoop主要用于从shell中调用的批处理作业)——我所遵循的java示例对我来说并不适用。我尝试过使用sqoop1.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。)

hc8w905p

hc8w905p1#

如果您只想将作业输出写入mysql,我建议您使用一种不同的输出格式,称为 DBOutputFormat 如下所述:
伴随类dboutputformat将允许您将结果写回数据库。设置作业时,调用conf.setoutputformat(dboutputformat.class);然后像以前一样调用dbconfiguration.configuredb()。
然后,dboutputformat.setoutput()方法定义将结果写回数据库的方式。它的三个参数是作业的jobconf对象、定义要写入的表名称的字符串和定义要填充的表字段的字符串数组。e、 例如,dboutputformat.setoutput(job,“employees”,“employeer_id”,“name”);。
您先前创建的同一个dbwritable实现足以将记录注入数据库。write(preparedstatement stmt)方法将在从reducer传递给outputcollector的dbwritable的每个示例上调用。在reduce结束时,这些preparedstatement对象将转换为insert语句,以针对sql数据库运行。
其中“如前所述”指本说明:

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

从mysql中读取,这与 DBInputFormat .

yhuiod9q

yhuiod9q2#

sqoop设计用于在mysql/其他关系数据库和hadoop/hbase之间导出/导入数据。一个非常好的关于sqoop的教程可以在这里找到,它解释了它的各种功能。不确定这是不是你想做的。
如果您需要在mapreduce作业中从mysql读写数据, DBInputFormat/DBOutput hadoop类可以按照@charles的建议使用

gcxthw6b

gcxthw6b3#

谢谢查尔斯和维卡斯。这无疑使我走上了正确的道路。最后我用了https://github.com/cwensel/cascading.jdbc 它使用hadoop类 DBInputFormat/DBOutput 使设置读写db的级联作业变得容易。
为了编写,我刚刚将我的tap的输出流更改为:

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 );

我也遇到过级联dbmigrate,但似乎这只是用于从db读取数据,而不是向它们写入数据。

相关问题