如何在Java程序中使用Sqoop?

22

我知道如何通过命令行使用sqoop。 但是不知道如何在Java程序中调用sqoop命令。 有人可以给一些代码示例吗?


1
Runtime.exec(command); 这是您所需要的吗?http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Runtime.html - kosa
5个回答

23
您可以通过将sqoop jar包包含在类路径中并调用 Sqoop.runTool() 方法来在Java代码中运行sqoop。您需要以编程方式创建所需的参数,就像它是命令行一样(例如--connect等)。请注意以下内容:
- 确保sqoop工具名称(例如导入/导出等)是第一个参数。 - 注意类路径的顺序 - 执行可能会失败,因为sqoop需要库的X版本,而您使用了不同版本。确保sqoop需要的库没有被您自己的依赖项掩盖。我曾遇到这样的问题:commons-io(sqoop需要v1.4),由于我使用了commons-io v1.2,所以出现了NoSuchMethod异常。 - 每个参数都需要在单独的数组元素上。例如,“--connect jdbc:mysql:…”应作为数组中的两个单独元素传递,而不是一个元素。 - sqoop解析器知道如何接受带双引号的参数,因此如果需要,则使用双引号(我建议总是这样做)。唯一的例外是fields-delimited-by参数,它期望单个字符,因此不要将其用双引号括起来。 - 我建议将命令行参数创建逻辑和实际执行分开,以便可以正确测试逻辑而不实际运行工具。 - 最好使用--hadoop-home参数,以防止对环境的依赖。 - 与 Sqoop.Main() 相比,Sqoop.runTool() 的优点在于它返回执行的错误代码。
希望这可以帮助到您。
final int ret = Sqoop.runTool(new String[] { ... });
if (ret != 0) {
  throw new RuntimeException("Sqoop failed - return code " + Integer.toString(ret));
}

强化学习


谢谢...我在网上搜索Sqoop文档以查看每种方法的详细信息...但是找不到...你可以告诉我关于Sqoop文档吗? - Pradeep Bhadani
我使用的文档位于http://archive.cloudera.com/cdh/3/sqoop/SqoopUserGuide.html#_controlling_the_hadoop_installation。但是,它们并没有描述执行Sqoop的那种方法。我使用了Sqoop源代码,并得到了Oozie项目(http://incubator.apache.org/oozie/)的一些帮助。 - Harel Ben Attia
我能够成功运行这个Java客户端,但它在本地文件系统上创建了part-m-0000文件,而不是HDFS。我检查了日志以查找作业是否在本地执行,作业ID本身指定为:job_local362447144_0001。如何像sqoop cli cmd一样运行这个程序? - shriyog
已解决上述问题,执行捆绑的jar文件需要使用yarn jar jar_name而不是java -jar jar_name - shriyog
当我运行这个程序时,出现了一个警告 SQOOP_CONF_DIR未设置,然后出现了错误 ERROR oracle.OracleConnectionFactory: 无法加载jdbc驱动程序类:oracle.jdbc.OracleDriver。但是当我从命令行运行相同的命令时,一切都正常。有什么建议吗? - Joha

12
在Java程序中使用Sqoop从MySQL导入数据到HDFS/HBase的示例代码如下。请确保您的类路径中有Sqoop jar包:
        SqoopOptions options = new SqoopOptions();
        options.setConnectString("jdbc:mysql://HOSTNAME:PORT/DATABASE_NAME");
        //options.setTableName("TABLE_NAME");
        //options.setWhereClause("id>10");     // this where clause works when importing whole table, ie when setTableName() is used
        options.setUsername("USERNAME");
        options.setPassword("PASSWORD");
        //options.setDirectMode(true);    // Make sure the direct mode is off when importing data to HBase
        options.setNumMappers(8);         // Default value is 4
        options.setSqlQuery("SELECT * FROM user_logs WHERE $CONDITIONS limit 10");
        options.setSplitByCol("log_id");

        // HBase options
        options.setHBaseTable("HBASE_TABLE_NAME");
        options.setHBaseColFamily("colFamily");
        options.setCreateHBaseTable(true);    // Create HBase table, if it does not exist
        options.setHBaseRowKeyColumn("log_id");

        int ret = new ImportTool().run(options);

正如哈雷尔所建议的那样,我们可以使用run()方法的输出来处理错误。希望这有所帮助。


3
有一个技巧对我很有效。通过ssh,您可以直接执行Sqoop命令。你只需要使用SSH Java库即可。这与Java独立,您只需包含任何SSH库和安装在远程系统中的sqoop,现在通过ssh连接到该系统并执行从MySQL导出数据到hive的命令。您必须遵循以下步骤。下载sshxcute java库:https://code.google.com/p/sshxcute/并将其添加到包含以下Java代码的Java项目的构建路径中。
import net.neoremind.sshxcute.core.SSHExec;
import net.neoremind.sshxcute.core.ConnBean;
import net.neoremind.sshxcute.task.CustomTask;
import net.neoremind.sshxcute.task.impl.ExecCommand;

public class TestSSH {

public static void main(String args[]) throws Exception{

    // Initialize a ConnBean object, the parameter list is IP, username, password

    ConnBean cb = new ConnBean("192.168.56.102", "root","hadoop");

    // Put the ConnBean instance as parameter for SSHExec static method getInstance(ConnBean) to retrieve a singleton SSHExec instance
    SSHExec ssh = SSHExec.getInstance(cb);          
    // Connect to server
    ssh.connect();
    CustomTask sampleTask1 = new ExecCommand("echo $SSH_CLIENT"); // Print Your Client IP By which you connected to ssh server on Horton Sandbox
    System.out.println(ssh.exec(sampleTask1));
    CustomTask sampleTask2 = new ExecCommand("sqoop import --connect jdbc:mysql://192.168.56.101:3316/mysql_db_name --username=mysql_user --password=mysql_pwd --table mysql_table_name --hive-import -m 1 -- --schema default");
    ssh.exec(sampleTask2);
    ssh.disconnect();   
}
}

工作正常,但日志似乎不正确。Sqoop作业已成功执行,控制台显示错误,指出作业失败了。“检查执行是否成功... 执行命令时发生错误:sqoop import --connect.... 错误信息:<sqoop job log is written here>” - sras

0

请按照 Vikas 给出的代码进行操作,这对我很有效。请将以下 jar 文件包含在类路径中并导入以下包:

import com.cloudera.sqoop.SqoopOptions; import com.cloudera.sqoop.tool.ImportTool;

参考库

  1. Sqoop-1.4.4 jar /sqoop
  2. ojdbc6.jar /sqoop/lib (用于 Oracle)
  3. commons-logging-1.1.1.jar hadoop/lib
  4. hadoop-core-1.2.1.jar /hadoop
  5. commons-cli-1.2.jar hadoop/lib
  6. commmons-io.2.1.jar hadoop/lib
  7. commons-configuration-1.6.jar hadoop/lib
  8. commons-lang-2.4.jar hadoop/lib
  9. jackson-core-asl-1.8.8.jar hadoop/lib
  10. jackson-mapper-asl-1.8.8.jar hadoop/lib
  11. commons-httpclient-3.0.1.jar hadoop/lib

JRE 系统库

1. resources.jar jdk/jre/lib 2. rt.jar jdk/jre/lib 3. jsse.jar jdk/jre/lib 4. jce.jar jdk/jre/lib 5. charsets,jar jdk/jre/lib 6. jfr.jar jdk/jre/lib 7. dnsns.jar jdk/jre/lib/ext 8. sunec.jar jdk/jre/lib/ext 9. zipfs.jar jdk/jre/lib/ext 10. sunpkcs11.jar jdk/jre/lib/ext 11. localedata.jar jdk/jre/lib/ext 12. sunjce_provider.jar jdk/jre/lib/ext

有时候,如果您的Eclipse项目使用JDK1.6,而您添加的库是JDK1.7,那么在创建Eclipse项目时配置JRE可能会出现错误。

Vikas,如果我想将导入的文件放入Hive中,我应该使用options.parameter(“--hive-import”)吗?


0
如果您知道可执行文件的位置和命令行参数,可以使用 ProcessBuilder,然后可以运行一个单独的 Process,Java 可以监视其完成并返回代码。

通常情况下,如果存在API集成点,最好使用该集成点而不是生成子进程。 - Turbo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接