本文已参与「新人创作礼」活动,一起开启掘金创作之路。
org.apache.hadoop.hive.serde2.SerDeException: java.io.IOException: Start of Array expected
背景
通过api获取数据进入hive时有1B这种不合规的空白文件
建表语句
shell 脚本
api="TodayHot"\
hadoop dfs -mkdir /jzytest/hive${api}/\
hive -e 'create external table if not exists jzy'$api'json\
( \
category string, \
description string, \
hotUrl string, \
addrlocal string, \
mediaEmotion int, \
mediaHeat int, \
pubUrl string, \
publishDate string, \
socialEmotion int, \
socialHeat int, \
title string, \
topicId string, \
totalEmotion int, \
totalHeat int\
)\
partitioned by (dt string)\
row format serde "org.apache.hive.hcatalog.data.JsonSerDe"\
LOCATION "hdfs:///jzytest/hive'$api'/";'
不需要导包,hcatalog自带,自建转的路径在$HIVE_HOME/hcatalog/share/hcatalog/hive-hcatalog-core-1.2.1.jar
HDP路径在/usr/hdp/2.4.2.0-258/hive-hcatalog/share/hcatalog/下
CDH路径在 /CDH解压(安装)目录/cloudera/parcels/CDH-5.13.2-1.cdh5.13.2.p0.3/lib/hive-hcatalog/share/hcatalog下
注意:版本不一样路径会有所变化
问题
查看hdfs上的文件发现有的文件大小是1B,文件还有空行还有一个‘\n’换行符
org.apache.hive.hcatalog.data.JsonSerDe没办法处理空行所以造成org.apache.hadoop.hive.serde2.SerDeException: java.io.IOException: Start of Array expected
删除hadoop对应的文件即可恢复
hadoop命令:hadoop dfs -rmr /filepath/filename
我这里的数据是每两个小时获取一次,自动放到hdfs上,并在hive上加载,所以考删除这种操作不可取
原因分析
出现问题的原因有两个
1.业务对接上没有说清楚,并不是每两个小时就能获取一次数据,其中0点,2点是服务器维护期,并不能获取到数据,所以在定时任务上应该排除,0点和2点。
2.比如上图所示303的渠道偶尔是没有数据的,那怎么处理呢?
要执行一下命令
#删除所有空行\
sed '/^\s*$/d' topic_id.out\
#删除所有回车空行\
awk '{printf("%s",$0)}' topic_id.out > topic_id.out
#awk不能输入,输出相同
awk '{printf("%s",$0)}' topic_id.out > topic_id.out.tmp
rm -rf topic_id.out
mv topic_id.out.tmp topic_id.out
解决文件还有空行还有一个‘\n’换行符问题,还没完这样就造成写空文件,空文件还用执行hdfs上传,hive数据加载吗?当然不用
所以要加上一个文件是否为空的判断
if [ -s ./topic_id.out ] ; then\
hadoop dfs -put topic_id.out /jzytest/hive${api}/dt=${dt}\
#rm -rf topic_id.out\
hive -e "alter table jzy${api}json add partition (dt='$dt');"\
hive -e "select topicId from jzy${api}json where dt=\"${dt}\" group by topicId;" > jzyhive${dt}.out\
fi
dt代表时间