问题现象:
oozie中跑的一个workflow,hql脚本的导出结果和预期不一致,出错。
漫长的DUBUG之路:
1.首先想到的是通过在Hue中来跑同一个hql脚本,查找问题。通过在oozie的log中找到解析完的hql,跑了下,结果发现和预期一致,头有点儿大。。。
2.经过分析hql,推测可能是和脚本中用到自己之前写的一个UDF有关。于是单独用这个UDF写了一个和问题中涉及业务相同的简单hql,分别在Hue和oozie中运行,发现结果不一致,初步定为到问题所在。
3.针对Hue和oozie,分别用这个UDF调用的HDFS中的jar,新建两个全新名字的UDF,保证Hue和oozie调用的为同一个名字的jar包,试验之后发现结果依然不一样,头更大了。。。
4.重新分析Hue和oozie的日志,发现在hql执行之前,系统add了两个相同名字的jar,就是这个UDF对应的jar。一个存在于集群中hive实例所在linux机器的/usr/lib/hive/aux/lib/目录下,一个存在于HDFS的目录下。之前在建UDF的时候,关联的都是HDFS中的jar包地址,但执行的时候,会把这两个jar都预先加载进来,jar中的包和类的结构完全一致,导致实际调用的时用的不是一个jar。至此,完全定位到问题的原因。
5.将这两个jar下载到本地,反编后发现HDFS中的版本较新,但还有BUG,而linux本地的版本较老,但BUG已经被改掉了。最终确定oozie调用hql的时候找的是UDF关联的jar包,而通过Hue执行的hql,默认优先找的是hive自己lib中的jar包,最终导致了这个问题。
6.追溯根源时发现,一开始UDF的jar包是直接放到hive自己的lib中的,后来觉得丢到HDFS中针对每个库来新建UDF更加灵活,就重新在HDFS中上传了一个,原有hive自己的lib那个jar却忘记删除了;另外,上传HDFS的那位同事本地git客户端那两天的问题,导致上传的版本漏了重要的BUG修改的一版,然后jar包又是在本地打包上传的,最终导致了这个问题。真是各种no zuo no die啊。。。
解决问题:
将所有地方的jar包再linux和HDFS上都删除,重新上传最新的jar到HDFS,DROP所有涉及的UDF并重新CREATE,最后重启hive和Hue,问题解决
经验和教训:
1.所有的jar和war都必须从jenkins服务器上获取
2.UDF涉及的jar包必须统一放在同一个地方,若实在需要改动,一定要彻底删除之前相关所有的jar包并重启hive