跳到主要内容

Hive基础与架构

什么是Hive ?

Hive 是基于Hadoop的一个数据仓库工具,可以将结构化和半结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能。 注意:

  • Hive本质是将HDFS转换成MapReduce的任务进行运算,底层由HDFS来提供数据存储。
  • Hive的元数据存储在SQL上,HBase的元数据存储在HDFS上。

Hive的优点和缺点

Hive是一种基于Hadoop的工具,它提供了SQL界面和查询语言来查询和分析存储在Hadoop上的大规模结构化数据。

优点:

  • 简化了复杂MapReduce任务:对于熟悉SQL而不是编写MapReduce代码的用户来说,可以更容易地使用SQL语法进行大规模数据分析。
  • 支持高度可扩展性:可以运行在一个集群上,并能够以并行方式执行查询,在海量数据情况下保持良好地性能。

缺点:

  • 延迟较高:相对于直接使用Hadoop的原生API,Hive的查询通常具有较高的延迟。这是由于转换SQL查询语句为底层MapReduce任务所带来的额外开销。
  • 不适合实时处理:Hive更适用于批处理任务而不是实时数据处理,因为它不支持动态数据更新和低延迟查询。 限制:在某些情况下,复杂的查询或特殊要求可能无法通过Hive来满足。

二、Hive架构与执行流程

Hive的执行流程

  1. 解析器(Parser):Hive首先==通过解析器将用户输入的HiveQL语句转换为抽象语法树(AST)==的形式。
  2. 语义分析器(Semantic Analyzer):Hive的语义分析器会对AST进行语义分析,包括验证表和列的存在性、检查数据类型、解析表达式等。
  3. 查询优化器(Query Optimizer):在语义分析完成后,Hive会对查询进行优化,包括重写查询计划、选择合适的连接方式、重新排序操作等,以提高查询性能。
  4. 查询计划生成器(Query Plan Generator):优化后的查询计划将被传递给查询计划生成器,生成逻辑查询计划。
  5. 物理计划生成器(Physical Plan Generator):逻辑查询计划会被传递给物理计划生成器,生成物理查询计划,包括选择合适的物理操作(如MapReduce、Tez等)和任务的划分。
  6. 执行器(Executor):生成的物理查询计划将被执行器执行,根据计划中的操作类型,将任务提交给相应的计算引擎(如MapReduce、Tez等)进行执行。
  7. 结果存储:执行完成后,查询结果将被存储在指定的位置,可以是本地文件系统、HDFS等。

Hive SQL转化为MR的过程

  1. 解析Hive SQL语句:首先,Hive会解析输入的Hive SQL查询语句,识别出查询的表、列以及其它相关的元数据信息。
  2. 查询优化和逻辑计划生成:Hive会将解析后的查询语句进行查询优化,根据表的统计信息和用户定义的参数选择最佳的执行计划。然后,Hive会生成逻辑查询计划,该计划描述了查询的逻辑执行流程。
  3. 逻辑计划到物理计划的转化:在这一步骤中,Hive将逻辑查询计划转换为物理查询计划,该计划描述了如何在MapReduce框架下执行查询。转换的过程通常包括将逻辑操作符映射到对应的MapReduce任务(如Map、Reduce、Join等),以及确定数据的分区和排序策略。
  4. 生成MapReduce作业:根据转换后的物理查询计划,Hive会生成一系列的MapReduce作业。每个作业会包括一个或多个Map任务和一个Reduce任务,它们负责执行查询并生成结果。
  5. 执行MapReduce作业:生成的MapReduce作业将被提交给Hadoop集群进行执行。在执行期间,MapReduce框架会负责将输入数据按照指定的分区方式划分到不同的Map任务中,并在Map和Reduce任务之间进行数据的传输和处理。
  6. 输出结果:一旦所有的MapReduce作业执行完成,Hive会从最后一个Reduce任务中获取最终的查询结果,并将其返回给用户或保存到指定的输出表中。

如何避免Hive中Join操作引起全表扫描?

使用合适的Join算法:根据数据的特点选择合适的Join算法,例如使用Map Join、Sort-Merge Join等。 调整表的存储格式:使用支持索引和列式存储等高效查询的存储格式,如Parquet或ORC。 对Join操作进行拆分:将大表进行水平分片或者预分区(Pre-partitioned)处理,以达到局部性原则,并使用Bucketing对小表数据进行哈希划分。 合理设置Join关联条件:确保关联条件可以做到快速过滤。

Hive如果不用参数调优,在map和reduce端应该做什么

Map端

  • 增加map任务的数量:可以通过设置’mapred.map.tasks’参数来增加map任务的数量,从而提高并行度和整体处理速度。
  • 压缩中间数据:可以使用Hive的压缩功能,如设置’hive.exec.compress.intermediate’参数为true,将中间数据进行压缩,减少磁盘I/O开销。

Reduce端

  • 增加reduce任务的数量:可以通过设置’mapred.reduce.tasks’参数来增加reduce任务的数量,从而提高并行度和整体处理速度。
  • 合理设置shuffle阶段的内存大小:可以通过调整’hive.shuffle.memory.limit’参数来控制shuffle阶段的内存大小,避免内存溢出或过多的磁盘I/O操作。
  • 使用Combiner函数:如果Reduce端的数据量较大,可以使用Combiner函数来进行部分聚合操作,减少传输给Reducer的数据量,提高性能。

三、Hive 使用

Hive分区和分桶的区别

Hive分区和分桶是Hive中用于优化查询性能的两种技术。

Hive分区: Hive分区是基于数据的某个列(通常是日期、地理位置等)进行的逻辑划分。分区可以将数据按照指定的列值划分成多个目录或文件,使得查询时只需要扫描特定分区的数据,从而提高查询性能。分区可以在创建表时定义,也可以在已有的表进行动态分区操作。分区的主要目的是减少查询时需要扫描的数据量,提高查询效率。

Hive分桶: Hive分桶是将数据分散存储到多个文件中,每个文件称为一个桶。分桶是通过对某些列的哈希函数计算得到的,可以在创建表时定义分桶数和分桶列。分桶的目的是将数据均匀地分布在多个桶中,使得查询时只需要扫描特定桶地数据,进一步提高查询性能。与分区不同的是,分桶不是将数据按照某些列值进行划分,而是通过哈希函数进行随机分配。