1.Tez简介
Tez 是支持 DAG 作业的开源计算框架,它可以将多个有依赖的作业转换为一个作业从而大幅提升 DAG 作业的性能。
从本质上讲,Tez 组成非常简单,只有两个组成部分:
- 数据处理管道引擎,其中一个引擎可以输入,处理和输出实现以执行任意数据处理
- 数据处理应用程序的主机,通过它可以将上述任意数据处理“任务”组合到任务 DAG 中,以根据需要处理数据。
- 总的来说MR任务在map和reduce阶段都会产生I/O落盘,但是Tez就不要这一步骤了。
- Tez采用了DAG(有向无环图)来组织MR任务。核心思想:将Map任务和Reduce任务进一步拆分,Map任务拆分为Input-Processor-Sort-Merge-Output,Reduce任务拆分为Input-Shuffer-Sort-Merge-Process-output,Tez将若干小任务灵活重组,形成一个大的DAG作业。
通过允许诸如 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包含的组件:
- 有向无环图(DAG)——定义整体任务。一个DAG对象对应一个任务。
- 节点(Vertex)——定义用户逻辑以及执行用户逻辑所需的资源和环境。一个节点对应任务中的一个步骤。
- 边(Edge)——定义生产者和消费者节点之间的连接。边需要分配属性,对Tez而言这些属性是必须的,有了它们才能在运行时将逻辑图展开为能够在集群上并行执行的物理任务集合。
Tez对外提供了6种可编程组件,简介如下:
- Input:对输入数据源的抽象,它解析输入数据格式,并吐出一个个Key/value
- Output:对输出数据源的抽象,它将用户程序产生的Key/value写入文件系统
- Paritioner:对数据进行分片,类似于MR中的Partitioner
- Processor:对计算的抽象,它从一个Input中获取数据,经处理后,通过Output输出
- Task:对任务的抽象,每个Task由一个Input、Ouput和Processor组成
- Master :管理各个Task的依赖关系,并按顺依赖关系执行他们
- 除了以上6种组件,Tez还提供了两种算子,分别是Sort(排序)和Shuffle(混洗),为了用户使用方便,它还提供了多种Input、Output、Task和Sort的实现
本文对于这些组件不着重介绍,接下来看执行Hive On Tez 时可以如下图划分:
当我们使用beeline 或者JDBC连接时,首先会创建一个Hive Session
- Hive on Tez Session 中可以包括1个或者多个application, 与数据库session相似,在同一个Tez Session中,可串行执行多个Tez Dag。Tez Session避免了AM的多次启动与销毁,在有多个DAG图的Tez作业(HQL任务)中大大减小了任务执行时间。
- 1个application 里会有1个或者多个DAG ,1个DAG 对应一个queryid 也对应一条SQL
- 1个SQL 中可能会生成多个Container 执行,而一个1Map Vertex或者Reduce Vertex 过程可能在多个Container 中执行,同一时间内Container 中只包含1个Task ,这里与Spark 中的Executor 中的Task 是不同的(Task 可复用已申请的Container,所以看到一个Container中在不同的时间点会有不同的Task复用Container这是相比MR引擎性能提升的一个重要的点)
看一个简单的示例,明白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=4096
tez.am.resource.cpu.vcores=3
hive.tez.Container.size=1024
hive.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 这样的文件夹中。在此文件夹下,可以找到会找到如下文件。
- syslog 这是 AM 正常启动之前的日志。
- syslog_dag_{yarn_app_id}_{dag_id} 这是每个 dag 的日志
- syslog_dag_{yarn_app_id}_{dag_id}_post 这是dag完成后每个dag的日志
所以通常只需要检查最后的 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-