超全面试汇总——Hive 超详细!!!带答案!!!持续更新中~

什么是 Hive ?

  • Hive 是基于 Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能(HQL),提供快速开发的能力。Hive本质是将SQL转换为 MapReduce的任务进行运算,减少开发人员的学习成本,功能扩展很方便。:
  • hive存的是和hdfs的映射关系,hive是逻辑上的数据仓库,实际操作的都是hdfs上的文件,HQL就是用sql语法来写的mr程序
  • 数据仓库是大多数企业“试水”大数据的首选切入点 ,因为数据仓库主要编程语言还是 SQL,而在大数据平台上,不论是 Hive 还是 SparkSQL,都是通过高度标准化的 SQL 来进行开发,这对于很多从传统数据仓库向大数据转型的开发人员和团队来说,是一种较为平滑的过渡。

Hive结构描述

  • Hive构建在Hadoop的HDFS和MapReduce之上,用于管理和查询结构化/非结构化数据的数据仓库

  • 使用HQL作为查询接口,使用HDFS作为底层存储,使用MapReduce作为执行层

  • 在这里插入图片描述

  • 用户接口:包括 CLI,JDBC,ODBC和 WUI

    • 其中最常用的是 CLI,CLI启动的时候,会同时启动一个 Hive 副本
    • Client 是 Hive 的客户端,用户连接至 Hive Server。在启动 Client 模式的时候,需要指出 Hive Server 所在节点,并且在该节点启动 Hive Server。
    • WUI 是通过浏览器访问 Hive
  • Hive内部执行流程:解释器、编译器、优化器、执行器

    • 解析器(解析SQL语句)、编译器(把SQL语句编译成MapReduce程序)、优化器(优化MapReduce程序)、执行器(将MapReduce程序运行的结果提交到HDFS
    • 词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在 HDFS 中,并在随后有 MapReduce 调用执行
  • 元数据存储。通常是存储在关系数据库如 mysql, derby 中

    • Hive 中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等。Hive 元数据默认存储在 derby 数据库,不支持多客户端访问,所以将元数据存储在 MySQL 等数据库,支持多客户端访问。
  • Hadoop:用 HDFS 进行存储,利用 MapReduce 进行计算

    • Hive 的数据存储在 HDFS 中,大部分的查询由 MapReduce 完成少数HiveSQL语句不会转化为MapReduce作业,直接从DataNode上获取数据后按照顺序输出。包含 * 的查询,比如 select * from tbl 不会生成 MapRedcue 任务

Hive的优势

  • Hive拥有统一的元数据管理,所以和Spark、Impala等SQL引擎是通用的。通用是指,在拥有了统一的metastore之后,在Hive中创建一张表,在Spark/Impala中是能用的,只需要共用元数据,就可以切换SQL引擎,涉及到了Spark sql和Hive On Spark
  • 可用SQL轻松访问数据,从而实现数据仓库任务,如提取/转换/加载(ETL),报告和数据分析。
  • 使存储的数据结构化
  • 支持MapReduce计算引擎 、Spark和Tez分布式计算引擎
  • 数据的存储格式多样 Hive中不仅可以使用逗号和制表符分隔值(CSV/TSV)文本文件,还可以使用Sequence File、RC、ORC、Parquet
  • 数据离线处理 日志分析

内部表、外部表、分区表、分桶表

  • 内部表:create table
    • 创建内部表时,没有特别指定,则默认创建的表都是管理表manage table(也称内部表),会将数据移动到数据仓库指向的路径不共享数据
    • hive.metastore.warehouse.dir(默认:/user/hive/warehouse),
    • 删除表时:在删除表的时候,内部表的元数据和数据会被一起删除
  • 外部表 :create external table
    • 当一份数据需要被共享时,可以创建一个外部表指向这份数据。
    • 若创建外部表,仅记录数据所在的路径通常在:/user/username/hive/warehouse/文件夹
    • 而外部表只删除元数据,不删除数据。这样外部表相对来说更加安全些,数据组织也更加灵活,方便共享源数据。
  • 分区表
    • 分区表使用的是表外字段,需要指定字段类型,并通过关键字partitioned by(partition_name string)声明,但是分区划分粒度较粗
    • 将数据按区域划分开,查询时不用扫描无关的数据,加快查询速度 。
  • 分桶表
    • 分桶使用的是表内字段,已经知道字段类型,不需要再指定。通过关键字 clustered by(column_name) into … buckets声明。分桶是更细粒度的划分、管理数据,可以对表进行先分区再分桶的划分策
    • 分桶最大的优势就是:用于数据取样,可以起到优化加速的作用
    • 对分桶字段求哈希值,用哈希值与分桶的数量取余,余几,这个数据就放在那个桶内

hive中 排序的种类和适用场景

  • order by 全局排序
    • 会对输入做全局排序,因此只有一个reducer(多个reducer无法保证全局有序),所以当输入的数据规模较大时,会导致计算的时间较长
    • 与数据库中 order by的区别在于在 hive 的严格模式下(hive.mapred.mode = strict)下,必须指定 limit ,否则执行会报错!
  • sort by 每个MapReduce排序
    • 不是全局排序,其在数据进入reducer前完成排序,单个有序。
    • sort by 的数据只能保证在同一reduce中的数据可以按指定字段排序
    • 不受 hive.mapred.mode 是否为strict ,nostrict 的影响,使用sort by 你可以指定执行的reduce 个数 (set mapred.reduce.tasks=
  • distribute by 每个分区排序
    • 按照指定的字段对数据进行划分输出到不同的reduce中
    • distribute by类似 MR 中 partition(自定义分区),进行分区,某个特定行应该到哪个 reducer ,通常是为了进行后续的聚集操作
  • distribute by + sort by
    • 分桶,保证同一字段值只存在一个结果文件当中,结合 sort by 保证 每个 reduceTask 结果有序
    • distribute by 和 sort by 的常见使用场景有:
      1. Map输出的文件大小不均
      2. Reduce输出文件不均
      3. 小文件过多
      4. 文件超大
  • cluster by
    • 同一字段分桶并排序,不能和 sort by 连用,除了具有 distribute by 的功能外还兼具 sort by 的功能
    • 但是排序只能是 升序 排序,不能像distribute by 一样去指定排序的规则为 ASC 或者 DESC

动态分区和静态分区的区别 + 使用场景

  • 静态分区
    • 表的分区数量和分区值是固定的。静态分区需要手动指定,列是在编译时期通过用户传递来决定的。
    • 需要提前知道所有分区。适用于分区定义得早且数量少的用例,不适用于生产。
  • 动态分区
    • 基于查询参数的位置去推断分区的名称,只有在 SQL 执行时才能确定,会根据数据自动的创建新的分区。
    • 应用场景:有很多分区,无法提前预估新分区,动态分区是合适的,一般用于生产环境。

hive 语句执行顺序

  • from … where … select … group by … having … order by … limit …

  • 注意事项

    • 使用分区剪裁、列剪裁,分区一定要加
    • 少用 COUNT DISTINCT,group by 代替 distinct
    • 是否存在多对多的关联
    • 连接表时使用相同的关键词,这样只会产生一个 job
    • 减少每个阶段的数据量,只选出需要的,在 join 表前就进行过滤
    • 大表放后面
    • 谓词下推:where 谓词逻辑都尽可能提前执行,减少下游处理的数据量
    • sort by 代替 order by
  • mysql执行顺序

    • from… where…group by… having… select … order by… limit …

Hive的几种存储方式

  • Text File format : 默认格式,数据不做压缩,磁盘开销大,数据解析开销大

  • Sequence File format

    • SequenceFile 是 Hadoop API 提供的一种二进制文件支持,其具有使用方便、可分割、可压缩的特点
    • SequenceFile 支持三种压缩选择:NONE, RECORD, BLOCK。 Record 压缩率低,一般建议使用 BLOCK 压缩。
  • 面向行:在一起存储的同一行数据是连续存储

  • RCfile format : RCFILE 是一种行列存储相结合的存储方式。首先,其将数据按行分块,保证同一个 record 在一个块上,避免读一个记录需要读取多个 block。其次,块数据列式存储,有利于数据压缩和快速的列存取。RCFile 目前没有性能优势,只有存储上能省 10% 的空间。

  • Parquet :

    • 列式数据存储。 查询比较快
    • Parquet支持嵌套的数据模型,每一个数据模型的schema包含多个字段,每一个字段有三个属性:重复次数、数据类型和字段名
    • 二进制方式存储的,是不可以直接读取和修改的
  • AVRO : avro Schema 数据序列化。

  • ORC : 对RCFile做了一些优化,支持各种复杂的数据类型 性能比较好

    • ORC 将行的集合存储在一个文件中,并且集合内的行数据将以列式存储。采用列式格式,压缩非常容易,从而降低了大量的存储成本。
    • 当查询时,会查询特定列而不是查询整行,因为记录是以列式存储的。
    • ORC 会基于列创建索引,当查询的时候会很快
    • ORC文件也是以二进制方式存储的,所以是不可以直接读取

列式存储的好处

  • 查询的时候不需要扫描全部的数据,而只需要读取每次查询涉及的列,这样可以将I/O消耗降低N倍,另外可以保存每一列的统计信息(min、max、sum等),实现部分的谓词下推
  • 由于每一列的成员都是同构的,可以针对不同的数据类型使用更高效的数据压缩算法,进一步减小I/O。
  • 由于每一列的成员的同构性,可以使用更加适合CPU pipeline的编码方式,减小CPU的缓存失效。

HQL转化为MapReduce的过程

  1. Antlr定义SQL的语法规则,完成SQL词法,语法解析,将SQL转化为抽象语法树AST Tree
    • HiveLexerX,HiveParser分别是Antlr对语法文件Hive.g编译后自动生成的词法解析和语法解析类
  2. 遍历AST Tree,抽象出查询的基本组成单元QueryBlock
    • QueryBlock是一条SQL最基本的组成单元,包括三个部分:输入源,计算过程,输出。简单来讲一个QueryBlock就是一个子查询
  3. 遍历QueryBlock,翻译为执行操作树OperatorTree
    • Hive最终生成的MapReduce任务,Map阶段和Reduce阶段均由OperatorTree组成。逻辑操作符,就是在Map阶段或者Reduce阶段完成单一特定的操作。
  4. 逻辑层优化器进行OperatorTree变换,减少mapreduce job,减少shuffle数据量
    • 谓词下推、合并线性的OperatorTree中partition/sort key相同的reduce (from (select key,value from src group bu key, value)s select s.key group by s.key;
    • Map端聚合
  5. 遍历OperatorTree,翻译为MapReduce任务
  6. 物理层优化器进行MapReduce任务的变换,生成最终的执行计划

Hive 和关系型数据库的区别

  • 适用范围不同: Hive时效性、延时性比较高 ,主要进行离线的大数据分析;数据库主要用在在线系统
  • 规模不同: Hive数据规模大,优势在 于处理大数据集
  • 查询语言不同: HQL 和 SQL
  • 存储位置不同: HDFS 和 本地
  • 执行方式: Hive执行MapReduce , Mysq执行Executor
  • 数据格式:Hive在加载数据的过程中不需要格式的转换,不会对数据本身进行修改 ;数据库中,不同数据库有不同存储引擎,加载的时候较慢

Hive和HBase的对比区别

  • Hive 数据仓库,Hive的本质其实就相当于将HDFS中已经存储的文件在Mysql中做了一个双射关系,以方便使用HQL去管理查询。
  • Hbase 数据库,面向列存储的非关系型数据库
  • Hive 适用于离线的数据分析和清洗,延迟较高
  • Hbase 适用于单表非关系型数据的存储,不适合做关联查询,延迟低适合在线业务
  • Hive 存储的数据依旧在DataNode上,编写的HQL语句会转换成MapReduce代码执行
  • HBase 数据持久存储放在DataNode上,以region的形式管理

Hive 小文件问题及解决

  • 小文件如何产生的

    • 动态分区插入数据,产生大量的小文件,从而导致map数量剧增;

    • 倒入数据时产生,每执行一次 insert 时hive中至少产生一个文件,文件数量=MapTask数量*分区数,insert 导入时至少会有一个MapTask。像有的业务需要每10分钟就要把数据同步到 hive 中,这样产生的文件就会很多。

    • -- 通过load方式加载数据
      load data local inpath '/export/score' overwrite into table A   -- 导入文件夹
      -- 通过查询方式加载数据
      insert overwrite table A  select s_id,c_name,s_score from B;
      
    • reduce数量越多,小文件也越多(reduce的个数和输出文件是对应的);

    • 数据源本身就包含大量的小文件

  • 造成的影响

    • Hive的角度 小文件会开很多map,一个map开一个JVM去执行,所以这些任务的初始化,启动,执行会浪费大量的资源,严重影响性能
    • HDFS文件元数据存储在NameNode 的内存中,在 内存空间有限的情况下,文件过多会影响NameNode 的寿命,同时影响计算引擎的任务数量,比如每个小的文件都会生成一个Map任务。
  • 如何解决

    • 使用 hive 自带的 concatenate 命令,自动合并小文件 alter table A concatenate;

      • concatenate 命令只支持 RCFILE 和 ORC 文件类型。
      • 使用concatenate命令合并小文件时不能指定合并后的文件数量,
    • 一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并)
      set mapred.min.split.size.per.node

       -- 设置map输入合并小文件的相关参数:
       set mapred.min.split.size.per.node
       -- 每个Map最小输入大小(这个值决定了合并后文件的数量)
       set mapred.min.split.size=256000000;  
       
       -- 设置map端输出进行合并,默认为true
       set hive.merge.mapfiles 
### Sqoop Hive Export 失败的解决方案 当遇到 Sqoop 将数据从 Hive 导出到关系型数据库时发生失败的情况,可能的原因涉及多个方,包括配置错误、权限不足以及目标数据库的状态异常等问题。以下是针对此问题的具体分析和解决方法: #### 配置文件检查 确保 `sqoop` 的连接参数正确无误。通常情况下,导出操作需要指定 JDBC URL 和目标表名。如果这些参数不匹配或者存在拼写错误,则可能导致作业失败[^1]。 ```bash sqoop export \ --connect jdbc:mysql://<hostname>:<port>/<database> \ --username <user> --password-file /path/to/password/file \ --table <target_table_name> \ --export-dir /hive/data/path/in/hdfs/ ``` 上述命令中的每一项都需要仔细核对以防止因路径或名称不符而导致的问题。 #### 数据类型兼容性验证 另一个常见问题是源端(Hive)的数据结构与目的端(RDBMS)之间的字段定义差异。例如日期时间戳格式的不同可能会引发转换错误。因此,在执行前应先确认两者的 schema 是否完全一致[^2]。 #### 权限管理 切换至合适的用户身份运行 sqoop 命令非常重要。“作为 root 用户工作就像开车时不系安全”,所以建议按照最佳实践由专门负责数据库操作的角色来完成此类任务。此外还需注意的是,某些虚拟环境中可能存在磁盘空间限制从而影响安装过程或其他大型事务处理活动的成功率。 #### 日志审查 最后但同样重要的一环就是查看详细的日志记录以便定位确切原因所在。通过增加 verbosity 参数可以获得更多诊断信息用于后续排查: ```bash -sqoop export ... -D mapreduce.job.queuename=<queueName> –verbose ``` 以上措施结合起来能够有效提升解决问题效率并减少不必要的麻烦。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值