二次开发DataX以支持HIVE分区表

问题

        最近在一个大数据的项目开发中使用到了数据同步工具DataX,但在使用过程中发现了DataX对HIve分区表的支持不太友好。

        具体体现在将数据库中的数据同步到HIVE分区表时,写入目录为HIVE表分区为dt=XXXX,如果不提前创建该分区,会报目录不存在的错误,如下图:

8cdbc6874e4846a7b12cc840a5ba7a15.png

 

原因分析 

         这个错误是由于DataX不支持在HDFS上创建目录导致的。

 

解决办法

        二次开发DataX,在写入时检测目录,若目录不存在自动创建此分区目录。

步骤:1.从GitHub下载datax源码  链接

           2.修改hdfswriter目录下的HdfsWriter.java源码,重写里面的prepare方法:

    @Override
    public void prepare() {
        //若路径已经存在,检查path是否是目录
        if (hdfsHelper.isPathexists(path)) {
            if (!hdfsHelper.isPathDir(path)) {
                throw DataXException.asDataXException(HdfsWriterErrorCode.ILLEGAL_VALUE,
                        String.format("您配置的path: [%s] 不是一个合法的目录, 请您注意文件重名, 不合法目录名等情况.",
                                path));
            }
            //根据writeMode对目录下文件进行处理
            Path[] existFilePaths = hdfsHelper.hdfsDirList(path, fileName);
            boolean isExistFile = false;
            if (existFilePaths.length > 0) {
                isExistFile = true;
            }
            if ("append".equalsIgnoreCase(writeMode)) {
                LOG.info(String.format("由于您配置了writeMode append, 写入前不做清理工作, [%s] 目录下写入相应文件名前缀  [%s] 的文件",
                        path, fileName));
            } else if ("nonconflict".equalsIgnoreCase(writeMode) && isExistFile) {
                LOG.info(String.format("由于您配置了writeMode nonConflict, 开始检查 [%s] 下面的内容", path));
                List allFiles = new ArrayList();
                for (Path eachFile : existFilePaths) {
                    allFiles.add(eachFile.toString());
                }
                LOG.error(String.format("冲突文件列表为: [%s]", StringUtils.join(allFiles, ",")));
                throw DataXException.asDataXException(HdfsWriterErrorCode.ILLEGAL_VALUE,
                        String.format("由于您配置了writeMode nonConflict,但您配置的path: [%s] 目录不为空, 下面存在其他文件或文件夹.", path));
            } else if ("truncate".equalsIgnoreCase(writeMode) && isExistFile) {
                LOG.info(String.format("由于您配置了writeMode truncate,  [%s] 下面的内容将被覆盖重写", path));
                hdfsHelper.deleteFiles(existFilePaths);
            }
        } else {
            LOG.info(String.format("您配置的路径: [%s] 不存在,自动为您创建此路径", path));
            hdfsHelper.createPath(path);
        }
    }

           3.修改hdfswriter目录下的HdfsHelper.java源码,在里面添加createPath方法:

    public boolean createPath(String filePath) {
        Path path = new Path(filePath);
        boolean exist = false;
        try {
            if (fileSystem.exists(path)) {
                String message = String.format("文件路径[%s]已存在,无需创建!",
                        "message:filePath =" + filePath);
                LOG.info(message);
                exist = true;
            } else {
                exist = fileSystem.mkdirs(path);
            }
        } catch (IOException e) {
            String message = String.format("创建文件路径[%s]时发生网络IO异常,请检查您的网络是否正常!",
                    "message:filePath =" + filePath);
            LOG.error(message);
            throw DataXException.asDataXException(HdfsWriterErrorCode.CONNECT_HDFS_IO_ERROR, e);
        }
        return exist;
    }

           4.打包修改后的源码,并替换掉集群的datax安装目录datax/plugin/writer/hdfswriter/hdfswriter-0.0.1-SNAPSHOT.jar即可。(在DataX-master根目录下的pom.xml文件核心组件、公共组件、reader/writer插件都以module的方式组装到一起了,把不需要的注释掉可加快打包速度)

 

处理结果

        二次开发后完美运行:

        b23e8af0324d435b9500f0bdcd335d10.png

 

 

你可能感兴趣的:(大数据,DataX,Web,大数据,java)