自定义扩展Sqoop的使用教程之二

467 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

支持用户定义自定义选项

Sqoop解析用户传递的参数并存储在SqoopOptions对象中。然后,此对象充当数据传输对象。在运行实际的MapReduce,MapReduce阶段甚至后处理阶段之前,此对象被传递到处理的各个阶段。用户自定义了新的工具就会产生一些新的选项,这些选项不会映射到SqoopOptions类的任何现有成员。用户可以向SqoopOption类添加新成员,这意味着用户必须在sqoop中进行更改并对其进行编译,这对所有用户来说都是不可能的。其他选择是使用extraArgs会员。这是一个字符串数组,其中包含可以直接传递给第三方工具(如mysqldump等)的第三方工具选项。此数组字符串每次都需要解析才能理解参数。支持用户定义工具的自定义选项的最优雅方式是 customToolOptionsmap。这是SqoopOption类的映射成员。开发人员可以解析用户定义的参数,并使用适当的键/值对填充此映射。当SqoopOption对象被传递到处理的各个阶段时,这些值将随时可用,并且每次访问都不需要解析。 示例如下:

  • --hbase-col
  • --hdfs-line-separator
  • --hbase-rowkey-separator SqoopOption对象中没有这些选项可用。Tool Developer可以覆盖该applyOptions方法,在此方法中,可以在customToolOptions映射中解析和填充用户选项。完成后,SqoopOption对象可以在整个程序中传递,这些值将可供用户使用。
public static final String HBASE_COL = "hbase-col";
public static final String HDFS_LINE_SEPARATOR = "hdfs-line-separator";
public static final String HBASE_ROWKEY_SEPARATOR = "hbase-rowkey-separator";

下面是解析上述选项并填充customToolOptions映射的示例applyOptions示例:

	@Override
    public void applyOptions(CommandLine in, SqoopOptions out) throws 	SqoopOptions.InvalidOptionsException {
        try {
            Map<String, String> optionsMap = new HashMap<String, String>();
            super.applyOptions(in, out);
            applyHBaseOptions(in, out);
            if (in.hasOption(EXPORT_PATH_ARG)) {
                out.setExportDir(in.getOptionValue(EXPORT_PATH_ARG));
            }
            if (in.hasOption(HDFS_LINE_SEPARATOR)) {
                optionsMap.put(HDFS_LINE_SEPARATOR, in.getOptionValue(HDFS_LINE_SEPARATOR));
            }
            if (in.hasOption(HBASE_COL)) {
                optionsMap.put(HBASE_COL, in.getOptionValue(HBASE_COL));
            }
            if (in.hasOption(HBASE_ROWKEY_SEPARATOR)) {
                optionsMap.put(HBASE_ROWKEY_SEPARATOR, in.getOptionValue(HBASE_ROWKEY_SEPARATOR));
            }
            if (out.getCustomToolOptions() == null) {
                out.setCustomToolOptions(optionsMap);
            }
        } catch (NumberFormatException nfe) {
            throw new SqoopOptions.InvalidOptionsException("Error: expected numeric argument.\n Try --help for usage.");
        }
    }

配置我们希望接收的命令行参数。您还可以指定所有命令行参数的描述。

	@Override
    public void configureOptions(ToolOptions toolOptions) {
        super.configureOptions(toolOptions);
        toolOptions.addUniqueOptions(getHBaseOptions());
        RelatedOptions formatOpts = new RelatedOptions(
                "设置相关mapreduce的参数");
        formatOpts.addOption(OptionBuilder.withArgName("dir")
                .hasArg()
                .withDescription("要导出数据的hdfs地址")
                .withLongOpt(EXPORT_PATH_ARG)
                .create());
        formatOpts.addOption(OptionBuilder.withArgName("char")
                .hasArg()
                .withDescription("hdfs数据的行分隔符")
                .withLongOpt(HDFS_LINE_SEPARATOR)
                .create());
        formatOpts.addOption(OptionBuilder.withArgName("char")
                .hasArg()
                .withDescription("hbase的列簇")
                .withLongOpt(HBASE_COL)
                .create());
        formatOpts.addOption(OptionBuilder.withArgName("char")
                .hasArg()
                .withDescription("hbase的复合rowkey的字段分隔符")
                .withLongOpt(HBASE_ROWKEY_SEPARATOR)
                .create());
        toolOptions.addUniqueOptions(formatOpts);
    }

ToolPlugin插件的基类

开发了Sqoop的扩展工具,你需要使用插件类包装并使用Sqoop注册该插件类。您的插件类应该从org.apache.sqoop.tool.ToolPlugin 和重写getTools()方法扩展 。 示例如下:

import org.apache.sqoop.tool.ToolDesc;
import org.apache.sqoop.tool.ToolPlugin;
import java.util.Collections;
import java.util.List;
public class ExtendHBasePlugin extends ToolPlugin {
    @Override
    public List<ToolDesc> getTools() {
        return Collections
                .singletonList(new ToolDesc("extendHbase", ExtendHBase.class, "HDFS上的数据导入到HBase"));
    }
}

注册用户的自定义插件

  1. 把自定义的jar文件拷贝到相关集群的./Sqoop/lib目录,并在sqoop-site.xml进行注册。
<property>
    <name>sqoop.tool.plugins</name>
    <value>org.apache.sqoop.extend.ExtendHBasePlugin</value>
    <description>A comma-delimited list of ToolPlugin implementations
      which are consulted, in order, to register SqoopTool instances which
      allow third-party tools to be used.
    </description>
  </property>

注册结束后再命令行输入:sqoop help 显示自定义的命令即注册成功。

[外链图片转存失败(img-N13FOIKI-1564577503259)(www.github.com/Tu-maimes/d…)]

Sqoop脚本示例

sqoop extendHbase \
    --hbase-table mytable \
    --column-family i \
    --hbase-row-key GDDM,GDXM \
    --export-dir /yss/guzhi/interface/gh.tsv \
    --hbase-rowkey-separator _ \
    --hdfs-line-separator \\t \
    --hbase-col GDDM,GDXM,BCRQ,CJBH,GSDM,CJSL,BCYE,ZQDM,SBSJ,CJSJ,CJJG,CJJE,SQBH,BS,MJBH

相关配置的简介

属性描述
extendHbase导出HDFS上的数据到HBase的指令
hbase-table要导入的HBase表名称,需要提前建表不支持自动建表
column-familyHBase表的列簇名称
hbase-row-keyHBase表Rowkey的设置,如果是指定多个列作为RowKey,彼此间的分隔符采用逗号间隔
export-dir要导出的HDFS上的文件
hbase-rowkey-separator如果RowKey采用的是复合列组合的方式的默认采用的分隔符是下划线,可以传递参数替换
hdfs-line-separatorHDFS上的文件数据行的分隔符
hbase-colHBase的列名称与HDFS上的数据列一一对应,彼此之间采用逗号分隔

==注意==:在设置RowKey时多个字段必须在hbase-col设置中必须包含。