问题背景:
最近在使用海豚调度DolphinScheduler的Datax组件时,遇到这么一个问题:之前给客户使用海豚做的离线数仓的分层搭建,一直都运行好好的,过了个元旦,这几天突然在数仓做任务时报错,具体报错信息如下:
问题一:datax读取hive分区表时,datax-hdfsReader 读取空目录报错
问题描述:
com.alibaba.datax.common.exception.DataXException: Code:[HdfsReader-08], Description:[您尝试读取的文件目录为空.]. - 未能找到待读取的文件,请确认您的配置项path: /user/hive/warehouse/dws.db/dws_index_business_xzkh/dt_date=2024-01-02
关键信息:
INFO HdfsReader$Job - 您即将读取的文件数为: [0], 列表为: [] Code:[HdfsReader-08], Description:[您尝试读取的文件目录为空.]. - 未能找到 待读取的文件,请确认您的配置项 path:具体路径 /user/hive/warehouse/dws.db/dws_index_business_xzkh/dt_date=2024-01-02
错误分析:
由于上层数据处理逻辑没有生成任何数据导致未生成任何目录和文件(如果上层 逻辑有自动创建目录,则会出现该问题)
问题很简单,因为该分区下没有数据文件所以报错。
这个解决也很容易。
1.当时想的是在shell里判断分区路径是否存在 然后hdfs dfs -ls /path |wc -l 看文件个数是否>0
后来发现这种不是很可取。
2.当时就觉得这种判断不太对,以前其他reader的时候怎么不见报错,hdfsReader就报错是吧。
哪里报错丢异常 我改成 warn就好了。
问题解决
找到报错点
处理方法一:
那全部原因就是 emptyDirIsExecption 再看
/**emptyDirIsExecption 默认值为true,当指定为false,空目录任务会返回成功,同步记录数为0**/
private Boolean emptyDirIsExecption=null;
再看,这里就是很清楚了
emptyDirIsExecption = this.readerOriginConfig.getBool(Key.EMPTY_DIR_IS_EXECPTION, true);
我们设置在json里设置 emptyDirIsExecption=false即可。
根据网上的这个方法我没改成,只能继续研究源码。
处理方法二:修改源码,最简单的办法就是把throw的异常,仅用LOG.warn打印出来即可。
将原有的抛出异常修改为打印错误记录终止本次调度任务(结果记为 成功避免后续任务正常进行,具体该如何处理需要根据具体业务决定),修改的 Java 文件为 位于 hdfsreader 工程下的 com.alibaba.datax.plugin.reader.hdfsreader.HdfsReader。
public List<Configuration> split(int adviceNumber) {LOG.info("split() begin...");List<Configuration> readerSplitConfigs = new ArrayList<Configuration>();// warn:每个slice拖且仅拖一个文件,// int splitNumber = adviceNumber;int splitNumber = this.sourceFiles.size();if (0 == splitNumber) {// throw DataXException.asDataXException(HdfsReaderErrorCode.EMPTY_DIR_EXCEPTION,// String.format("未能找到待读取的文件,请确认您的配置项path: %s", this.readerOriginConfig.getString(Key.PATH)));//异常处理逻辑修改LOG.warn(String.format("未能找到待读取的文件,请确认您的配置项path: %s", this.readerOriginConfig.getString(Key.PATH)));LOG.info("split() end");LOG.info("Task exited with return code 0");System.exit(0);}
重新打包后,替换安装目录下 /data/datax/plugin/reader/hdfsreader 下的 hdfsreader-0.0.1-SNAPSHOT.jar 包。(记得如果是ha,还要提前将hdfs-site和core-site文件打到包里),如果海豚调度搭建的是集群,请将集群中的都修改了,不用重启海豚直接执行任务就行。
问题二:datax读取hive分区表时,datax-hdfsReader 读取目录不存在报错
问题描述:
DataX 组件读取的目录不存在导致调度任务报错,错误信息截图如下:
关键信息:
ERROR HdfsReader$Job - 无法读取路径[具体路径] 下的所有文件,请确认您的配 置项 fs.defaultFS, path 的值是否正确,是否有读写权限,网络是否已断开! java.io.FileNotFoundException: File 具体路径 does not exist.
错误分析:
由于上层数据处理逻辑没有生成任何数据导致未生成表分区目录。
问题解决:
修改源码,在目录读取前做判断如果目录不存在打印系统错误日志并终止本次调 度任务(结果记为成功避免后续任务正常进行,具体该如何处理需要根据具体业务决定), 修改的 Java 文件为位于 hdfsreader 工程下的 com.alibaba.datax.plugin.reader.hdfsreader. DFSUtil。
重新打包后,替换安装目录下 /data/datax/plugin/reader/hdfsreader 下的 hdfsreader-0.0.1-SNAPSHOT.jar 包。(记得如果是ha,还要提前将hdfs-site和core-site文件打到包里),如果海豚调度搭建的是集群,请将集群中的都修改了,不用重启海豚直接执行任务就行。
这里要说一下,我们改源码请找自己对应版本的源码,别找错了
【DATAX】datax读取hive分区表时,空分区任务报错问题解决_datax hdfdsreader 读 hive分区表
【DataX】Dolphinscheduler调度Datax任务读取Hive分区表案例_目前支持orc,sequence,rcfile,text,csv五种格式的文件,请检查您文件类型和文
最简单dophinscheduler 集成datax步骤_dolphinescheduler datax
Dolphinscheduler配置Datax踩坑记录_dolphinscheduler datax
datax-hdfsReader空目录报错_datax hdfsreader
gitee的代码传送门:https://gitee.com/mirrors_alibaba/DataX