spark-streaming读kafka数据到hive遇到的问题
在项目中使用spark-stream读取kafka数据源的数据,然后转成dataframe,再后通过sql方式来进行处理,然后放到hive表中,
遇到问题如下,hive-metastor在没有做高可用的情况下,有时候会出现退出,这个时候,spark streaminG的微批作业就会失败,
然后再启重动hive-metastore进程后,作业继续正常执行,数据就有丢失.
分析如下:
第一步,观察日志发现,
我原来的代码这么写的:
xx.foreachRdd(rdd=>
processRdd(rdd)
updatezkOffset(rdd)
)
原以为,如果任务不成功,就应该不更新offset,
原想的是,如果processrdd出现异常,则不会执行后面的updateoffset,
但processrdd是在线程池中运行的,它出现的异常只是warning,根本不影响后面的updateoffset.
故需要修改代码,把updateoffset部分放置processrdd中,当其执行完成后调用即可.
第二步测试:
经过测试发现,把updateoffset部分放置processrdd后,模拟hive metastore出问题,
spark-streaming 任务失败,然后offset 确实没有更新.
但问题在这里,下一批次的作业,读取的offset并不是你没有更新的那一个,而是它计算出来的.
例如假设batch1 job读取的是0-20,batch2 job读取的就是21-40,batch3 job读取的是41-60
即使batch1 job处理任务失败了,但是后面的batch2 job或batch3 job 读取数据并执行成功了,
它就会把自己的offset更新.
第三步测试:
经测试发现,使用可恢复的方式,即使用checkpoint.
spark streaming保留了最近的五个batchjob信息,但是也不能解决上面遇到的问题,
如果hive metastore出问题,再恢复,原来存储的元数据信息也会被新的给替换掉了.
想到的解决方案:
1.如果batch job出现失败的情况,就直接让它退出,这是一种解决思路.
2.还使用手工更新zookeeper offset的方法,
如果出现部分batch job失败的情况,仍不退出,但是我们给应用写一个支持传入
offset 范围的版本,重新执行,把数据补进去.
另外,如何提交spark streaming 已经失败的batch job?