《Hive 编程指南》读书笔记
作者:CHO 体系 马壮
前言:
最近刚接触写 Hive SQL,却发现许多查询的执行速度远不如预期。为了提升查询效率,我去阅读了《Hive 编程指南》,希望通过理解其底层机制来找到优化的方式,并为未来能编写出高效的 SQL 奠定基础。谨以此文做个记录。
一、Hive 因何而生
先有 Hadoop 再有 Hive
Hadoop 实现了一个计算模型——MapReduce,它可以将计算任务分割成多个处理单元然后分散到一群家用的或服务器级别的硬件机器上,从而降低计算成本并提供水平可伸缩性。但是这套编程模型对于大多数数据分析分析师较为复杂和地销,即便是 Java 开发编写 MapReduce 程序也需要很多时间和精力。基于此,Hive 提供了基于 SQL 的查询语言(HiveQL),这边能够让拥有 SQL 知识的用户能够轻松使用 Hadoop 进行大数据分析,因为 Hive 的底层会自动将这些查询转换为 MapReduce 任务。
二、Hive 组成模块

所有的命令和查询都会进入 Driver,通过该模块对输入进行解析编译,对需求的计算进行优化,然后按照指定的步骤执行。
Hive 通过 JobTracker 通信来初始化 MapReduce 任务,需要处理的数据文件是存储在 HDFS 中的,而 HDFS 是由 NameNode 进行管理的。
Metastore(元数据存储)是一个独立的关系型数据库,Hive 会在其中保存表模式和其他系统元数据。
三、HQL 执行流程

简单来说,Hive 会从 Hadoop 分布式文件系统(HDFS)中读取原始数据,然后根据查询定义,在单节点(本地模式)或者 Hadoop 集群上(集群模式)执行数据处理。处理完成后,Hive 会将结果输出到 HDFS 或者其他指定的存储位置。
那么,Hive 的执行时间主要花费在哪儿呢?我们可优化的部分是哪部分?
Hive 的执行时间主要花费在以下几个阶段:
1.查询编译:Hive 将 HiveQL 查询编译成一个逻辑执行计划,这个计划描述了如何执行查询。此阶段包括语法分析、语义分析、生成逻辑计划、逻辑计划优化和生成物理计划(通常是 MapReduce 作业)。
2.任务调度:编译生成的 MapReduce 作业被提交到 Hadoop 集群的资源管理器(如 YARN),等待资源调度和作业执行。
3.数据读写:读取存储在 HDFS 上的数据以及写入最终结果到 HDFS,这个过程涉及大量的磁盘 I/O 操作,尤其是在处理大量数据集时。
4.MapReduce 作业执行:包括
1.Map 阶段:执行过滤、投影等操作;
2.Shuffle 阶段:Map 任务输出的中间数据在网络上传输并在 Reduce 节点上进行排序和合并;
3.Reduce 阶段:执行聚合、排序等操作;
5.网络传输:在 MapReduce 的 Shuffle 阶段,中间数据需要在集群节点之间传输,这可能导致显著的网络延迟。
通常,MapReduce 作业的执行时间(尤其是 Shuffle 和 Reduce 阶段)以及数据的读写操作是 Hive 查询中最耗时的部分,也是我们优化过程中主要关注的部分,接下来我们看下有哪些常见的优化方式。
四、Hive 常见的优化方式
本地模式
map-side JOIN 优化

并发执行
动态分区调整
合并小文件
数据倾斜优化
数据倾斜指的是在分布式处理过程中,数据不均匀地分配给各个节点处理,导致部分节点负载过重,而其他节点负载轻松,从而影响整体计算效率。数据倾斜出现的原因主要如下:
1.键值分布不均匀:有些键值对应的数据远多于其他键值;
2.量相同键值:大量数据使用相同的键(如 null 或者特定的默认值)进行分组;
3.不合理的 JOIN 操作:在 JOIN 大表时,如果小表的某个键值在大表中分布不均,导致 JOIN 后的结果倾斜;
4.不合理的分区策略:数据分区时没有考虑数据的实际分布,导致分区不均匀。
主要解决方案有:
1.自定义分区策略:实现自定义分区期,根据数据的特点进行更合理的分区;
2.扩展键值:对倾斜的键添加随机前缀或编号,使其分散到多个分区;
3.过滤大键值数据:识别出倾斜的键值(如 null、空值)进行单独处理或过滤掉不重要的数据。
最后就是我们关系型数据库常用的优化方式同样也适用与 Hive。例如通过使用小表关联大表的方式减少查询数据量,提高查询效率;Hive 同样也有索引的概念,通过建立索引减少 MapReduce 的输入数据量,但同样和关系型数据库一样,是否使用索引需要进行仔细评估,因为维护索引也需要额外的存储空间,而且创建索引同样消耗计算资源;Hive 同样也有 EXPLAIN 关键字,用于查询 Hive 时如何将查询转化为 MapReduce 任务的,使用 EXPLAIN EXTENDED 语句可以产生更多的输出信息,有兴趣大家可自行查看。
总体而言,这本书对于刚入门学习写 HQL 的我来说收货很大,让我初步对 Hive 有了基本的认知,也让我对我写的 SQL 有了更深入的了解。但是该书中的 Hive 应该版本比较低了,和我们现在所使用的可能有所偏差,不过入个门足够了。本文除了书中内容还有些我个人理解,如有错误,欢迎指正。
版权声明: 本文为 InfoQ 作者【京东科技开发者】的原创文章。
原文链接:【http://xie.infoq.cn/article/1e734b49040a34c11a3c6b499】。文章转载请联系作者。
评论