解决 Error: java.io.EOFException: Premature EOF from inputStream 问题

一、问题

1.问题过程

在日志解析任务过程中,突发报错,任务一直都很稳定,怎么回突然报错了呢?心头一紧

2.详细错误类型:

查看日志发现如下错误

21/11/18 14:36:29 INFO mapreduce.Job: Task Id : attempt_1628497295151_1290365_m_000002_2, Status : FAILED
Error: java.io.EOFException: Premature EOF from inputStream
	at com.hadoop.compression.lzo.LzopInputStream.readFully(LzopInputStream.java:75)
	at com.hadoop.compression.lzo.LzopInputStream.readHeader(LzopInputStream.java:114)
	at com.hadoop.compression.lzo.LzopInputStream.<init>(LzopInputStream.java:54)
	at com.hadoop.compression.lzo.LzopCodec.createInputStream(LzopCodec.java:83)
	at com.hadoop.mapreduce.LzoSplitRecordReader.initialize(LzoSplitRecordReader.java:58)
	at org.apache.hadoop.mapred.MapTask$NewTrackingRecordReader.initialize(MapTask.java:548)
	at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:786)
	at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341)
	at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:164)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.Subject.doAs(Subject.java:422)
	at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1907)
	at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:158)

通过搜索引擎查询该错误,结果指向dfs.datanode.max.transfer.threads参数到达上限,比如
https://blog.csdn.net/zhoujj303030/article/details/44422415

查看集群配置,发现该参数与修改为8192。排查其他问题。

后来发现是日志文件中有一个lzo的空文件,删除后,重新执行任务,执行成功。

二、解决

为了防止再次出现上述问题,在执行解析任务之前,编写脚本删除lzo空文件

1.遍历指定路径下的文件

for file in `hdfs dfs -ls /xxx/xxx/2037-11-05/pageview | sed '1d;s/  */ /g' | cut -d\  -f8`;
do  
	echo $file; 
done

结果输出:

/xxx/xxx/2037-11-05/pageview/log.1631668209557.lzo
/xxx/xxx/2037-11-05/pageview/log.1631668211445.lzo

2.判断文件是否为空

for file in `hdfs dfs -ls /xxx/xxx/2037-11-05/pageview | sed '1d;s/  */ /g' | cut -d\  -f8`;
do  
	echo $file; 
	lzoIsEmpty=$(hdfs dfs -count $file | awk '{print $3}')
	echo $lzoIsEmpty;
	if [[ $lzoIsEmpty -eq 0 ]];then 
		#为空,删除文件
		hdfs dfs -rm $file;
	else
		echo "加载数据"
	fi
done

3.最终脚本

#遍历日志类型
for type in webclick error pageview exposure login
do
    #判断文件夹大小
    isEmpty=$(hdfs dfs -count /xxx/xxx/$do_date/$type | awk '{print $2}')
    if [[ $isEmpty -eq 0 ]];then #为空
        echo "------ Given Path:/xxx/xxx/$do_date/$type is empty" 
    else #不为空,判断文件
		for file in `hdfs dfs -ls /xxx/xxx/$do_date/$type | sed '1d;s/  */ /g' | cut -d\  -f8`;
		do  
			echo $file; 
			lzoIsEmpty=$(hdfs dfs -count $file | awk '{print $3}')
			echo $lzoIsEmpty;
			if [[ $lzoIsEmpty -eq 0 ]];then 
				echo 删除文件:$file
				hdfs dfs -rm $file;
			fi
		done
		
		echo ================== 将 $do_date  $type 类型的日志数据导入ods层 ==================
		... 处理日志解析逻辑
   fi
done

更多推荐