1.Tez简介
Tez 是支持 DAG 作业的开源计算框架,它可以将多个有依赖的作业转换为一个作业从而大幅提升 DAG 作业的性能。
从本质上讲,Tez 组成非常简单,只有两个组成部分:
通过允许诸如 Apache Hive 和 Apache Pig (已停止更新)之类的项目运行复杂的 DAG 任务,Tez 可以用于处理数据,该数据以前需要执行多个 MR 作业,而现在在单个 Tez 作业中(图下的绿色圆圈表示为一个作业),如下所示:
测试环境:
1、Cloudera Runtime 7.1.7 启用Kerberos
2、Cloudera Manager 7.4.4
2.Hive On Tez 解析
2.1.结构组成
Tez 计算引擎结构更加类似于Spark,但却有所区别,
Tez包含的组件:
Tez对外提供了6种可编程组件,简介如下:
本文对于这些组件不着重介绍,接下来看执行Hive On Tez 时可以如下图划分:
当我们使用beeline 或者JDBC连接时,首先会创建一个Hive Session
看一个简单的示例,明白SQL、Session 、application、dag、queryid、Container、Task以及日志中的Map 和reduce之间的关系。
Map (Input-Processor-Sort-Merge-Output)和Reduce(Input-Shuffer-Sort-Merge-Process-output)只是任务一个过程,执行在1个或多个Task上,跟 Container没有直接的关系。它与CDH5 Hive 使用MR引擎中的Map Reduce 是不同的。
Session 当创建一个hive 链接时,便会生成一个sessionid ,默认空闲5分钟超时,该参数在Tez 配置中搜索 tez.session.am.dag.submit.timeout.secs 查看。
默认同一个Session 中对应的application id 是同一个。如下图,超过5分钟后重新执行,日志中会有Tez session was closed.Reopening的相关信息输出
session reopen 后SQL任务的DAG会重新生成一个application,但是对应的sessionid 是同一个,因此默认的Application Name 一致
为了方便大家查看它的运行信息,运行一个稍微复杂的SQL,并把Task 运行的关键信息摘取出来,举例如下:
可以使用cat /tmp/application_1640571570835_309624.log | grep 'taskAttemptId' 命令过滤掉其他信息,便于更直观的了解Task 在Container里的运行情况。
如下图所示:
container_e14_1640571570835_309624_01_000002 中有两个Task 分别为attempt_1640571570835_309624_1_00_000000_0 与 attempt_1640571570835_309624_1_02_000000_0 ,可以看到是00结束后 02才初始化运行,它们是复用的同一个Container (备注:01在另外的一个container_e14_1640571570835_309624_01_000006 上)
2.2 计算资源与配置
本文档中着重讲述下面的几个参数在YARN上的分配和计算,更详细配置可以查看文末的参考文档[5]
Hive on Tez 任务运行时使用的资源计算如下:
使用的内存大小为:
Container 数量*hive.tez.container.size + 1*tez.am.resource.memory.mb
使用的cpu数量为:
Container 数量* hive.tez.cpu.vcores +1*tez.am.resource.cpu.vcores
集群的参数如下,运行所用如下图所示:
tez.am.resource.memory.mb=4096tez.am.resource.cpu.vcores=3hive.tez.Container.size=1024hive.tez.cpu.vcores=2
只有AM生成时:
AM+ Container 时:
2.2.1 Tez AM的内存和CPU 大小配置
Tez AM的内存大小和cpu数量配置方式如下图,
CM > Tez > 配置 里:
tez.am.resource.memory.mb 默认2GB,该参数通常需要根据实际情况调整,否则容易出现内存溢出情况,也可以通过如 set tez.am.resource.memory.mb=4096; 来设置会话级别的参数,该参数大小不可以超过yarn.nodemanager.resource.memory-mb 的大小,否则运行任务时会有Cannot allocate containers as requested resource is greater than maximum allowed allocation 异常提示。
tez.am.resource.cpu.vcores 默认为1 ,多数情况下无需调整,与上面的类似,该参数的值不可超过 yarn.nodemanager.resource.cpu-vcore 的大小,否则运行任务时会有同上的异常信息。
<property><name>tez.am.resource.cpu.vcores</name><value>3</value></property>
超配后运行作业会有如下异常:
2.2.2 Tez Container 的内存和CPU大小配置
Tez Container 的内存大小和cpu数量配置方式如下图,
CM > Hive on Tez > 配置 里:
hive.tez.Container.size大小默认为4G,该参数与tez.am.resource.memory.mb类型,通常需要根据实际情况调整,否则容易出现内存溢出情况,可以通过如set hive.tez.container.size=8096; 来设置会话级别的参数,该参数大小不可以超过yarn.nodemanager.resource.memory-mb 的大小,否则执行任务时会有Vertex's TaskResource is beyond the cluster container capability报错 。
hive.tez.cpu.vcores 在CM中显示为-1 , 当hive.tez.cpu.vcores设置小于1时,将被mapreduce.map.cpu.vcores值覆盖,该参数通常无需调整。该参数的值不可超过 yarn.nodemanager.resource.cpu-vcore 的大小,否则运行任务时Hive on Tez 任务会卡住,并且在ResouceManager 日志中可以看到一直在刷Invalid resource request! Cannot allocate Containers as requested resource is greater than maximum allowed allocation. 相关的异常信息。
当hive.tez.cpu.vcores 配置的值超过yarn.nodemanager.resource.cpu-vcore的值后,任务卡在如下图所示的位置,只有AM 的生成,无法申请到Container的资源,并且ResouceManager 日志 有如下图异常
2.2.3 Tez Task 的内存和CPU 大小配置(可不配置)
将这两个参数单独拿出来是因为容易让人误解,它们在CDP的Hive on Tez 作业是没有效果的。虽然在Tez 的参数中有tez.task.resource.memory.mb以及tez. task.resource.cpu.vcores 两个参数配置Task 的内存和CPU,但是这两个参数会被
hive.tez.container.size 和hive.tez.cpu.vcores 所覆盖,运行作业时Task 的资源将以Container的配置为准,所以这两个参数无需改动。
如下图,hive.tez.container.size=1024 和hive.tez.cpu.vcores=1 ,
tez.task.resource.memory.mb=5120,tez.task.resource.cpu.vcores=2 ,实际运行时申请的资源是以Container配置为准。
也可以通过过滤TaskAttemptId 来定位Task 运行在哪些Container 中
2.3 日志查看和分析
Tez 会将大部分异常传播到客户端。因此,需要首先检查客户端日志以查找有用信息。如果客户端日志没有传达有用的信息,可以检查 yarn 应用程序日志。
用户可以调用命令"yarn logs -applicationId {your_app_id}"来获取yarn应用程序日志到您的本地目录。此命令仅在启用YARN日志聚合时可用。CDP集群中默认开启日志聚合,可以在CM>YARN>配置中搜索 yarn.log-aggregation-enable 检查该参数是否有开启。如果未启用日志聚合,需要在每个节点管理器机器上查找日志。
获得yarn应用程序日志后。可以先查看 Tez AM 日志,Tez AM 是在第一个 yarn app 容器中启动的,因此它位于 Container_{yarn_app_id}_000001 这样的文件夹中。在此文件夹下,可以找到会找到如下文件。
所以通常只需要检查最后的 dag 日志即可找到错误。
命令行扩展:
使用yarn logs -applicationId {your_app_id} 命令来获取Hive on tez 应用日志可以结合如下参数一起使用。
-show_application_log_info
显示 ContainerIds属于特定应用。可以结合这与--nodeAddress获取所有的 ContainerIds容器上的特定节点管理器。
-show_Container_log_info
显示容器日志元数据,包括日志文件名称,日志的大小文件。可以结合该参数用 --ContainerId 来获取记录元数据特定的容器,或 --nodeAddress 获取日志所有的元数据容器上的特定点管理器。
如图Application Tags 也就是hive_20220104113302_618d4581-9df4-47a5-b1b0-ada072c6d701 对应的就是application_1640872724002_0002 第一个生成dag 计算的SQL,注意:部分简单的SQL并不生成dag,在日志。如下图syslog_dag_1640872724002_0002_1 也就是该SQL 执行的所有日志,如执行的SQL报错信息一般在该日志下
3.文档总结
Tez 执行性能 相对于 Map Reduce 的性能有显著提升,也有更为合理资源管理,同样因为资源复用与DAG导致的Hive on Tez 的运行时出现问题了查看日志更为复杂,相信通过本文的分析可以对大家在排查Hive on Tez问题时有所帮助。
参考文献:
[1] https://tez.apache.org/[2] https://cwiki.apache.org/confluence/display/TEZ/How+to+Diagnose+Tez+App[3] https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties[4] https://github.com/apache/tez[5] https://community.cloudera.com/t5/Community-Articles/Demystify-Apache-Tez-Memory-Tuning-Step-by-Step/ta-p/245279