Hive知识点整理

Hive知识点整理

简介

  1. Hive解决的问题是海量结构化日志的数据处理
  2. 基于Hadoop的一个数据仓库工具,将结构化数据映射为一张表,提供HQL的类SQL查询功能
  3. Hive的数据存储在HDFS上
  4. Hive计算逻辑的底层默认实现是MapReduce
  5. Hive由Yarn调度
  6. Hive相当于Hadoop的客户端,因此是非分布式的

优缺点

  1. 类SQL语法,学习成本低
  2. 延迟较高,常用于实时性要求不高的场合,例如离线计算
  3. 吞吐量大(高延迟、高吞吐特性继承自Hadoop)
  4. 支持用户自定义函数(UDF, UDAF, UDTF)
  5. 不法表达迭代式计算(继承自Hadoop)
  6. Hive调优粒度较粗

架构

hive_arch

访问方式

  1. hive shell: 通过CLI访问
  2. java连接hive: 通过JDBC访问

Driver

  1. 解析器:将HQL解析成AST,对AST进行语法分析,检查错误
  2. 编译器:将AST编译成逻辑执行计划
  3. 优化器:对逻辑执行计划进行优化
  4. 执行器:将逻辑执行计划转换为物理运行计划,例如MapReduce或Spark

元数据存储 (Meta Store)

  • 元数据包括:表名、表所属数据库、表的拥有者、列、分区字段、表的类型(是否为外部表)、表数据所在目录
  • 元数据默认存储在自带的derby数据库中,生产环境下一般用MySQL替代默认的derby存储元数据

与数据库区别

  1. 数据库的数据一般存储在本地文件系统,Hive的数据存储在HDFS
  2. 数据库支持增删改查,Hive不建议对数据进行改的操作
  3. Hive不能建索引,只能遍历
  4. Hive的执行引擎是MapReduce,适合海量数据的非实时性查询
  5. Hive的可扩展性基于Hadoop,可扩展性强

Hive排序

order by

全局排序:只有一个reducer

sort by

区内排序:多个reducer,每个reducer内部分别排序

distribute by

分区:指定按字段进行分区

cluster by

分区排序:相当于distribution bysort by的结合,先分区,每个分区内排序,适用于分区字段和排序字段相同的情况,但是不支持降序,只能升序

分区与分桶

分区

  • 将数据按分区键的值存储到不同目录下
  • 分区字段会存储在元数据中,在where中指定分区的话,只会扫描指定的分区,可以避免全表扫描
  • 支持多级分区,partition by (x, y, z, ...),底层就多级目录嵌套
  • 主要应用场景:按时间(天,小时)给日志分区

分桶

  • 将数据按分桶键的值存储在多个文件中
  • 主要应用场景:分桶抽样, tablesample(bucket x out of y)

压缩与存储

Hive支持的文件存储有Textfile, Sequencefile, ORC, Parquet

行存储与列存储

  • 行存储:一行的数据存储在一起,列存储:一列的数据存储在一起
  • Textfile, Sequencefile是行存储,ORC, Parquet是列存储

ORC

  1. Index Data: 一个轻量级的index, 每隔1w行做一个索引,记录某行的各个字段在Row Data中的offset
  2. Row Data: 存储具体数据,先取一个index内的行,对这些行按列存储,对每列进行编码,分成多个Stream存储
  3. Stripe Footer: 各个Stream的类型,长度信息
  4. 每个文件有一个File Footer, 存每个Stripe的行数,每个Column的数据类型;每个文件尾是一个PostScript,存储文件的压缩类型以及File Footer长度。读文件时,会seek到文件尾部读PostScript,从里面解析到File Footer的长度,再读File Footer,解析到各个Stripe的信息,再从前往后读内容

Hive调优

Fetch抓取

Hive中某些查询可以不走MapReduce,例如SELECT * FROM xxx,Hive可以直接读取表目录下所有文件,直接输出结果. Fetch抓取触发条件由hive-default.xml.template文件的hive.fetch.task.conversion字段决定,默认为more,当该字段为more时,全局查找、字段查找 (SELECT col FROM table)、FILTER查找、limit语法都不会走MapReduce.

<property>
    <name>hive.fetch.task.conversion</name>
    <value>more</value>
    <description>
    Expects one of [none, minimal, more].
    Some select queries can be converted to single FETCH task minimizing latency.
    Currently the query should be single sourced not having any subquery and should not have any aggregations or distincts (which incurs RS), lateral views and joins.
    0. none: disable hive.fetch.task.conversion
    1. minimal  : SELECT STAR, FILTER on partition columns, LIMIT only
    2. more     : SELECT, FILTER, LIMIT only (support TABLESAMPLE and virtual columns)
    </description>
</property>

本地模式

当数据量小时,Hive可以在单机上处理所有任务,缩短执行时间。set hive.exec.mode.local.auto=true,Hive会根据输入数据量的大小(hive.exec.mode.local.auto.inputbytes.max, 默认128M)和文件个数(hive.exec.mode.local.auto.input.files.max, 默认4个),自动决定是否开启本地模式。

小表join大表:mapjoin功能

控制mapjoin开启的参数hive.auto.convert.join默认值为true, 大表小表阈值的参数hive.mapjoin.smalltable.filesize默认为25M,表示默认情况下会对小表进行mapjoin优化,将小表读入内存,25M以下是小表

大表join大表

大表join大表时,如果某一张表或者两张表的连接键含有很多null,造成数据倾斜,给处理空key的reduce任务带来很大的压力,拖慢任务的执行速度。

  1. 空key过滤:join之前通过子查询is not null过滤连接键
  2. 空key转换:有时连接键为null的字段不能过滤,则将空key转换为随机key(注意随机key不能和原来的key有重合的可能),使得这些记录能够均匀分配到不同的reducer处理

group by优化

Map端聚合

Map端聚合类似MapReduce的combiner操作,在MapTask中预聚合一部分数据,hive.map.aggr默认为true,表示默认开启Map端聚合

负载均衡

hive.groupby.skewindata参数控制是否启用负载均衡,默认为false. 当发现任务出现严重的数据倾斜时,set hive.groupby.skewindata=true,会开启2个MR job. 第一个执行负载均衡,job将相同的key随机发送到不同的reducer,然后reducer根据key对数据进行聚合,每个reduce中的数据的key不一定相同. 第二个job执行计算逻辑,将第一个job的结果进行一次聚合,计算最终结果。

count(distinct)优化

COUNT(DISTINCT key)对key去重后计数的操作只用一个ReduceTask,当数据量过大时,reduce节点的计算压力过大。因此,大数据量时,要将COUNT(DISTINCT key)操作用GROUP BY替换

SELECT COUNT(DISTINCT id) FROM xxx;     -- 原查询
SELECT COUNT(id) FROM (SELECT id FROM xxx GROUP BY id) a;       -- 优化后的查询

分区分桶

explain查看执行计划(类似MySQL)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章