小站重新装修,欢迎到访。
标签 #Hive

oozie的使用总结

本篇不是oozie的教程,官网的文档虽然比较粗糙,但已经非常全面,可直接参考,下文总结下oozie使用中遇到的一些问题(持续更新中)。

oozie版本:3.3.2

###时区问题

oozie默认使用UTC时区,而服务器上可能是CST,建议统一使用GMT+0800。

  • 不要修改oozie-default.xml,无效。在oozie-site.xml中添加:
1
2
3
4
<property>
<name>oozie.processing.timezone</name>
<value>GMT+0800</value>
</property>
  • 可以用oozie info --timezones来查看支持的时区
  • 使用GMT+0800后,时间不可以再使用形如2014-01-24T13:40Z的格式,要使用对应的形如2014-01-24T13:40+0800的格式
  • 还有一点比较重要,即oozie web console的TimeZone设置要和上述一致,否则你在web console中看到的时间在感官上都是不正确的

###Hive相关
oozie会启动一个MR job来启动hive client,需要在你的oozie app里自行指定hive的配置,以及提供相关lib,因为不确定是哪一台节点,所以需要给每一台计算节点都分配hive metastore的权限。

hive-site.xml

  • 使用指定hive-site.xml位置,下例中对应位置为该oozie app所在的目录,也可以指定一个绝对的HDFS路径

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <action name="trackinfo">
    <hive xmlns="uri:oozie:hive-action:0.2">
    <job-tracker>${jobTracker}</job-tracker>
    <name-node>${nameNode}</name-node>
    <job-xml>hive-site.xml</job-xml>
    <configuration>
    <property>
    <name>mapred.job.queue.name</name>
    <value>${queueName}</value>
    </property>
    </configuration>
    <script>trackinfo.hql</script>
    <param>label=${wf:actionData('date')['lastday']}</param>
    </hive>
    <ok to="end"/>
    <error to="fail"/>
    </action>

####hive的lib

  • 在job.properties中设置oozie.use.system.libpath=true
  • 使用oozie.libpath=/path/to/lib指定lib路径

####metastore

  • 切记要把metastore的相应jdbc驱动放到lib里
  • 别忘了给每个计算节点授权,否则连接不上metastore

####hive action的错误如何分析?
hive action执行失败,怎么分析原因呢?在oozie的web console中,打开因出错被KILL的action节点,打开Console URL即可以看到对应的MR jobdetails页面,一般错误信息在Map的日志里,打开你就会发现,日志的内容涵盖了hive job的定义、hql以及控制台输出,足够分析错误原因了。

###前一天
由于我司大多数job是计算前一天的数据,故需在调度时动态计算前一天的日期字符串,使用shell action结合 可以捕捉控制台输出,输出格式需为A=B,这样就可以使用${wf:actionData('A')['B']}提取所需的字符串了。

1
2
3
4
5
6
7
8
9
10
11
12
13
<action name="date">
<shell xmlns="uri:oozie:shell-action:0.1">
<job-tracker>${jobTracker}</job-tracker>
<name-node>${nameNode}</name-node>
<exec>${cmd}</exec>
<argument>-d</argument>
<argument>1day ago</argument>
<argument>+lastday=%Y-%m-%d</argument>
<capture-output/>
</shell>
<ok to="nextStep"/>
<error to="fail"/>
</action>

其中cmd=/bin/date

###权限
遇到HDFS相关的权限问题,请通过修改oozie app提交用户或修改HDFS文件权限的方式自行解决。

记一次Hive线上问题的排查

前几天监控到一个Hive Job CPU偏高,而且长时间无法停止,我最初怀疑是死循环,于是着手排查了下问题,不算太曲折。虽然已经过去多日,细节都快忘了,不过幸亏chrome的history里保留了一些痕迹,让我能把这件事分享出来。

由于权限有限,只能从运行Hive Job的这台机器查起。首先是要查看下对应的java进程的运行状况,用jstack,失败,抛出如下异常:

1
sun.jvm.hotspot.debugger.DebuggerException: sun.jvm.hotspot.debugger.DebuggerException: get_thread_regs failed for a lwp

首次见到,于是google之,得知是JDK6u23之前的一个bug(参考这里),查看了下故障机的JDK版本,果然低了,奇怪的是只有这台比较低,先不管,升级到1.6.0_31。

继续jstack,发现没有异常的锁等待。多次jstack查看,主线程都在这个方法里(代码行偶尔不同):

1
org.apache.hadoop.mapred.lib.CombineFileInputFormat.getMoreSplits(JobConf, Path[], long, long, long, List<CombineFileSplit>)

于是基本确定是在上述方法里发生了死循环,于是继续搜索:hadoop getMoreSplits infinite loop,发现社区有个相关的issue。关键是这句话:

At first, we lost some blocks by mis-operation . Then, one job tried to use these missing blocks. At that time getMoreSplits() goes into the infinite loop.

上面是因为mis-operation导致的,我没有听说有误操作发生,于是去读代码,同时汇报进展,同事听后告诉我确有一台DataNode挂掉了,那么如果确实是一台DataNode的宕机导致了block missing,则相关文件的replication应该为1,继续hadoop fs查看相关文件的replication,果不其然。

虽然不是十分明确地指出事故原因,但从一系列的分析来看,基本可以断定是上述原因。读了下上述issue提交的patch,大概的思路是在while(true)中检测是否出现了上述情况,如果出现的话,则强行忽略掉出问题的block,起初我还试图把这个patch打进来,但转念一想,这样会导致出现数据丢失,根本就不治本,问题的实质不是hadoop的错,而是hadoop的使用者没能很好地理解HDFS,在hadoop的世界里,错误是常态,虽然hadoop允许将replication设置为1,但用户必须明白的是hadoop没有义务也没有能力确保用户数据万无一失,用户必须学会通过设置合适的参数来避免单点问题。最终我给出了两条建议:

  • 严禁用户将replication设置为1
  • 加强线上机器监控
1

博主是一个不是很聪明的码农。完美主义者,强迫症中期。这里会记录一些回忆和点滴,以博为镜。

武器库:

该博客使用基于  Hexo  的  simpleblock  主题。博客内容使用  CC BY-NC-SA 3.0  授权发布。最后生成于 2017-02-20.