一、Hive是什么?

Hive提供了一种SQL(结构化查询)语言,可以将结构化的文件映射为一张表,查询存储在HDFS上的数据或者其他在HDFS上的文件系统,例如HBase。

优点:

  • 操作接口采用类SQL的语法,快速开发
  • 避免学习MapReduce,减小学习成本
  • 支持用户自定义函数
  • 处理大数据便捷

缺点:

  • 执行延迟比较高,自动生成的MapReduce作业比较慢
  • 表达能力有限,体现在迭代式算法无法表达、MapReduce数据处理流程限制,无限实现效率更高的算法
  • 不支持记录级别的更新、插入、删除操作

二、Hive架构

用户接口(Client):CLI、JDBC/ODBC、WEBUI

元数据(Meta store):表名、表所属数据库、表的拥有者、列/分区字段、表的类型(内、外部表)、表的数据所在目录等

驱动器(Driver)

  • 解析器:将SQL字符串转换成抽象语法树AST,一般都用第三方工具完成,比如antlr
  • 编译器:将AST编译成逻辑执行计划
  • 优化器:将逻辑执行计划进行优化
  • 执行器:将逻辑执行计划转化为物理计划,例如MR/SPARK

三、Hive内外部表

内部表、外部表:是否被external修饰

内部表存储的位置:hive.metastore.warehouse.dir(默认是 /user/hive/warehouse)

外部表数据存储位置是自己规定的(如果没有location)在HDFS上的/user/hive/warehouse下以外部表的表名创建一个文件夹

内部表的数据由Hive自身管理

外部表的数据有HDFS管理

创建表:

创建内部表时,数据将移动到数据仓库指向的路径

创建外部表时,仅记录数据所在路径

删除表:

删除内部表时,元数据和数据一起被删除

删除外部表时,只删除元数据

外部表的优点:

  • 外部表不会加载到Hive的默认仓库,减少数据的传输,同时还能和其他外部表共享数据
  • 使用外部表,hive不会修改源数据,不用担心数据损坏或丢失

四、Hive数据倾斜

  • 什么是数据倾斜?

    数据倾斜主要表现在 map/reduce 程序执行时,reduce节点大部分执行完毕,但有一个或者几个reduce节点运行很慢,导致整个程序的处理时间很长。

    这是因为某一个key的条数比其他key多很多,这条key节点所处理的数据量比其他节点大很多,从而导致某几个节点迟迟运行不完。

  • 数据倾斜的原因

    join:其中一个表较小、但key集中,分发到某一个或者几个reduce上的数据远远高于平均值

    大表与大表:,但分桶的判断字段0值、空值过多,这些空值都由一个reduce处理,非常慢

    group by:group by维度过小,某值的数量过多,处理某值的reduce非常耗时

    count distinct,某特殊值过多,处理此特殊值的reduce非常耗时

  • 原因:

    • key分布不均匀
    • 业务数据本身特性
    • 建表是考虑不周
    • 某些sql本身就有数据倾斜
  • 现象:

    • 任务进度长时间维持在99%,查看任务监控页面,只发现有少量(1个或几个)reduce子任务未完成。因为其处理的数据量和其他reduce差异过大。
    • 单一reduce的记录数与平均记录数差异过大,通常可能达到3倍甚至更多。最长时长远远大于平均时长。
  • 解决方案

    • 参数调节

      • hive.map.aggr = true
      • hive.groupby,skewindata = true
    • map端部分聚合,相当于combiner

    • 有数据倾斜的时候进行负载均衡,当选型设置为true,生成的查询计划会有两个MR Job。

      • 第一个mr job中,map的输出结果会随机的分布到reduce中,每个reduce做部分聚合操作,并输出结果。这样处理的结果是相同的group by key有可能被分发到不同的reduce中,从而达到负载均衡的目的。
      • 第二个mr job再根据预处理的数据结果按照 group by key分布到reduce中(这个过程保证相同的key被分布到同一个reduce中)最后完成最终的聚合操作。
    • sql语句调节

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      如何join:
      关于驱动表的选取,选用join key分布最均匀的表最为驱动表,做好列裁剪和filter操作,以达到两表做join的时候,数据量相对较少。
      使用map join让小的维度表(1000条以下记录数)先进内存,在map端完成reduce

      大表join大表:
      把空值的key变成一个字符串加上随机数,把倾斜的数据分到不同的reduce上,由于nul值关联不上,处理后并不影响最终结果。

      count distinct大量相同特殊值:
      count distinct时,将值为空的情况单独处理,如果是计算count distinct,可以不用处理,直接过滤,在最后结果+1

      group by维度过小:
      采用sum() group by的方式来替换count(distinct)完成计算

      特殊情况特殊处理:
      业务逻辑优化效果一般的情况下,可以将数据倾斜的数据单独拿出来处理,最后union回去。