benguo.me
域名年龄: 12年10个月21天HTTP/1.1 500 Internal Server Error 访问时间:2016年11月05日 19:09:17 服务器:Apache/2.4.7 (Ubuntu) 语言环境:PHP/5.5.9-1ubuntu4.14 过期时间:1984年01月11日 13:00:00 缓存控制:不缓存,必须更新, max-age=0 其他指令:不缓存 文件大小:242 连接:关闭 类型:text/html; charset=utf-8 网站编码:utf-8
笨郭大城里的小程序员如何进行Hive debugwithout comments老实说,一般在使用Hive进行数据分析工作时,很少会遇到什么hive的BUG。但有时候我们自己写的UDF或者SerDe会遇到些诡异的问题,尤其是在升级hive的版本时,api变动或hive内部添加了新的执行优化机制可能使原来工作的UDF或SerDe不再正常工作。所以还是需要掌握些DEBUG手段,以备不时之需。本文主要总结我在使用HQL执行Query类操作时用到的DEBUG方法,主要有这么几板斧:打开hive DEBUG日志explain查看plan.xml使用IDE远程Debug下面一一简单说明下方法,例子先不举了,一时手头没特合适的CASE。打开hive DEBUG日志这个比较基本,也很容易操作。出问题时先打开,兴许有些有用的信息。另外我们自己的UDF或SerDe里也可以输出些DEBUG日志,方便定位问题:hive -hiveconf hive.root.logger=DEBUG,consoleexplain即在HQL前加上EXPLAIN,比如EXPLAIN SELECT * FROM ...不过这个在查错误的时候用处不大,我还没用它定位到什么BUG。不过在查一些性能问题,或者查看下hive到MR任务的执行过程时会用得着查看plan.xml先得说下hive的执行过程。大体上是这样的:hive 客户端(一般是hive cli,入口类为CliDriver)把HQL翻译成MR执行计划(Operator树)并序列化到 plan.xmlplan.xml 上传到hdfs上hive 客户端新起一进程,提交MapReduce程序,其入口类为ExecDriver,ExecDriver的Mapper会在setup阶段读取plan.xml,反序列化成Operator树结构,然后执行。所以plan.xml精确的描述了MR程序具体的执行过程,而且xml文件层次清楚,比explain输出更丰富的信息,也很易读。MR执行计划很少出问题,但我们可以借助plan.xml排除一些怀疑会出问题的点,比如确认是翻译阶段的问题,还是MR执行阶段的问题。曾经有一次定位UDF使用的BUG,最开始怀疑是hive生成MR执行计划出错了,但通过查看plan.xml,我们确认翻译阶段没问题。进而开始使用终极手段来看问题:IDE远程DEBUG,单步跟踪,这个我们稍后说。查看plan.xml的方法,有点trick。HIVE cli在生成 plan.xml时,会打印日志:Generating plan file <some_temp_dir>/plan.xml但hive 任务执行完毕时,会把它删掉。所以你得手快,或者想办法让hql跑的时间长点,比如sleep一下之类。如果有什么参数可以让hive不删plan文件,留言给我, 先行谢过。使用IDE远程DEBUG之所以说是终极手段,有两个意思:如果上面的几个手段都定位不到问题,这个八成能帮你找到问题,反正我屡试不爽用起来着实得费些力气:首先,最好能用hive本地模式复现BUG否则还得找到具体执行此任务的Hadoop节点IP,更麻烦了。 启用本地模式的方法是:# hadoop0.20SET mapred.job.tracker=local;# hadoop 1及以上版本set mapreduce.framework.name=local;有一个参数容易混淆:SET hive.exec.mode.local.auto=false;这实际上是hive的一个优化,即在hive认为合适的时候,自动启用local模式以更快的计算(数据量比较小的时候有用)。所以设置此参数,不一定会以local模式运行。为JVM 添加远程调试参数参数比较简单,很多文章里都有介绍(不过我觉得IBM这篇最好):-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8765suspend=y 是为了让我们有机会把IDE attach到被调试进程上,否则又是个拼手快的活儿了。麻烦之处在于,从启动hive到运行MR程序过程中,需要启动两个JVM(也有只启动一个的情况,稍后再说):hive cli需要一个JVM,入口类CliDriver提MR程序需要一个JVM,入口类ExecDriver一般我们希望调试MR阶段的代码,所以我们需要保证在启动第一个JVM时,不监听调试端口,只在第二个JVM上加上述参数。或者至少两阶段使用不同的端口,否则第二个JVM端口冲突就无法启动了。hive启动CliDriver和ExecDriver都通过 ‘hadoop jar’来启动。所以添加JVM参数可以通过HADOOP_CLIENT_OPTS环境变量添加, 但是, 直接export HADOOP_CLIENT_OPTS 是不行的,因为hive在 调用hadoop jar之前,要调用hadoop version 来确定版本,HADOOP_CLIENT_OPTS对hadoop version同样生效,所以只能改hadoop启动脚本了,通常是/usr/lib/hadoop/bin/hadoop,要在这段代码附件设置:...elif [ "$COMMAND" = "jar" ] ; then# 这里添加 HADOOP_CLIENT_OPTSHADOOP_CLIENT_OPTS="$HADOOP_CLIENT_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8765"CLASS=org.apache.hadoop.util.RunJarelif [ "$COMMAND" = "checknative" ] ; then...还不够,需要区分JVM1 和JVM2的参数,hive提供了三个变量设置(看代码纠出来的,官方文档还没介绍):HIVE_DEBUG_RECURSIVE: 告诉hive要把 HADOOP_CLIENT_OPTS 变量传给子JVMHIVE_MAIN_CLIENT_DEBUG_OPTS和HIVE_CHILD_CLIENT_DEBUG_OPTS:hive在将HADOOP_CLIENT_OPTS传给子JVM时,会把 HADOOP_CLIENT_OPTS中HIVE_MAIN_CLIENT_DEBUG_OPTS的值的部分,替换成HIVE_CHILD_CLIENT_DEBUG_OPTS的值(好绕啊)所以最终的代码应该是:...elif [ "$COMMAND" = "jar" ] ; thenif ! echo "$HADOOP_CLIENT_OPTS"|fgrep 'dt_socket' ; thenHADOOP_CLIENT_OPTS="$HADOOP_CLIENT_OPTS -Xde
© 2010 - 2020 网站综合信息查询 同IP网站查询 相关类似网站查询 网站备案查询网站地图 最新查询 最近更新 优秀网站 热门网站 全部网站 同IP查询 备案查询
2024-12-02 16:22, Process in 0.0045 second.