Hive调优

本文详细介绍了Hive的各种优化技术,如数据压缩、存储格式、fetch抓取策略、join连接优化、本地模式、动态分区、JVM重用、并行执行、推测执行以及SQL优化方法,包括列裁剪、分区裁剪和避免笛卡尔积等,旨在提升查询效率和解决数据倾斜问题。
摘要由CSDN通过智能技术生成

主要手段有:       Hive数据压缩        Hive数据储存格式        fetch抓取         join连接       本地模式  动态分区        严格模式    JVM重用    并行执行    推测执行   
SQL优化(列裁剪, 分区裁剪, groud by 操作, count(distinct), 笛卡尔积,)
注意:hive可以通过 执行计划explain +select语句 查看执行步骤,确定优化方案和思路.

1.hive数据压缩

  1. 核心原理:对hive数据减少map端到reduce端的传输量,提升效率.
  2. MapReduce支持的压缩格式有:

        DEFAULT(默认形式)        Gzip        bzip2        LZO        LZ4        Snappy(大多数情况下选用)

        Gzip压缩后的数据较小,且压缩和解压的速度比较快,但Snappy压缩后的数据大小与之相差虽不大的情况下, 拥有更高的解压缩的速度.

2.Hive数据存储

  1. 核心原理:设置map端压缩,减少map到reduce的传输量,提升效率.
  2. 分为行存储和列存储两种形式
  3. 行存储类型: texfile  和  squencefile
  4. 列存储类型: orc 和 parquet     注意:orc默认内置压缩格式是zlib,但在实际中会替换为Snappy.
  5. 区别:
  • 行存储:  数据是一行行存储,在查询全部数据的是相对较快,但查询某一列字段名的数据比较影响性能,且由于每行中的各列数据类型不一致,不能获得一个较高的压缩比,压缩式空间利用率不高.
  • 列存储:  数据是一列列存储,在查询某一列字段名的数据相对较快,但查询和小量数据全部数据的是相对较慢,且由于每列数据类型相同,能够获得一个较高的压缩比,压缩式空间利用率高.

3.fetch抓取

  1. 核心原理:能不走MapReduce尽量不走MapReduce.
  2. 三种模式:可选择
  • more (默认值): 可以保证在执行全表扫描, 查询某几个列, 进度limit操作,还有简单条件查询4种情况都不会走MR.
  • minimal :  保证执行全表扫描,查询某几个列,简单limit操作3种情况可以不走MR
  • none : 全部的查询的SQL 都执行MR

4.本地模式(默认关闭)

1.核心原理:小文件能走本地MapReduce模式,尽量走本地模式.

2.如何开启:

set hive.exec.mode.local.auto=true;  -- 默认值为: false

3.开启本地模式后, 在什么情况下执行本地MR:

只有当输入的数据满足以下两个特性后, 才会执行本地MR
 

        set hive.exec.mode.local.auto.inputbytes.max=51234560;   -- 默认为 128M

        -- 设置本地MR最大处理的数据量

        set hive.exec.mode.local.auto.input.files.max=10; -- 默认值为4

        -- 设置本地MR最大处理的文件的数量

5.join优化

1.核心原理

        map端可以提前join,减少reduce工作量; 所有数据能提前过滤就提前过滤,减少join数据量.

2.通用优化方案:

        可以通过底层map 端 join实现,还可以sql语句join之前提前过滤数据或者转换数据实现

3.小表join大表优化方案:(小表在前,打表在后)

-- 默认开启
set hive.auto.convert.join = true; -- 默认为true  开启mapJoin支持 
set hive.mapjoin.smalltable.filesize= 25000000;  -- 设置 小表的最大的数据量  23.84m

4.中表和大表join

        中表过滤后可能会变成小表,也就意味着可能符合map端join的条件.

5.大表join大表

1) 能在join之前过滤操作, 一定要在join前过滤, 以减少join的数据量, 从而提升效率
2) 如果join字段上, 有很多的空值null值,获取其他无效数据, 这些值越多 就会导致出现数据倾斜
	方案一: 提前过滤掉
select * 
from (select * from 表1 where 字段名 is not null) 别名1 join 
     (select * from 表2 where 字段名 is not null) 别名2 on 关联条件;
	方案二: 将null值替换为随机数, 从而减少数据倾斜影响
select * 
from (select case when 字段名 is null then rand() else 字段名 end  from 表1) 别名1 join
   (select case when 字段名 is null then rand() else 字段名 end  from 表2) 别名2 on 关联条件;
3) 基于分桶表(大文件分为多个小文件)

6.动态分区

核心原理:动态生成分区目录,先复制表结构(like方式),再插入数据.

-- 不关闭严格模式下动态分区
    insert into table 新分区表  select * from 原分区表 ;
-- 关闭严格模式下动态分区
-- 关闭严格模式: 
set hive.exec.dynamic.partition.mode=nonstrict;
insert into table 新分区表 partition(分区字段名) select * from 原分区表 ;

7.调整map和reduce数量

核心原理:够用刚刚好

1.map数并非越多越好:

        如果一个任务有很多小文件(远远小于块大小128m),则每个小文件也会被当做一个块,用一个map任务来完成,而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的map数是受限的。

2保证每个map处理接近128m的文件块并非更好:

        比如有一个127m的文件,正常会用一个map去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,如果map处理的逻辑比较复杂,用一个map任务去做,肯定也比较耗时。

3.reduce数量并非越多越好:
        如果reduce设置的过大,对整个作业会产生一定的影响。①过多的启动和初始化reduce也会消耗时间和资源;②另外有多少个reduce,就会有多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题.

4. 只能有一个reduce的情况:
    1) 执行order by操作
    2) 执行不需要group by直接聚合的操作
    3) 执行笛卡尔积

8.并行执行(默认关闭)

核心原理:  sql语句底层多个阶段如果互不依赖,可以设置并行执行提升效率

        在执行一个SQL语句的时候, SQL会被翻译为MR, 一个SQL有可能被翻译成多个MR, 那么在多个MR之间, 有些MR之间可能不存在任何的关联, 此时可以设置让这些没有关联的MR 并行执行, 从而提升效率 ,

set hive.exec.parallel=false;              -- 打开任务并行执行,默认关闭
set hive.exec.parallel.thread.number=8;  -- 同一个sql允许最大并行度,默认为8。

9.严格模式(默认关闭)

核心原理:效率低下的sql尽量不要编写执行

        hive提供一种严格模式, 主要目的,是为了限制一些效率极低的SQL,防止其执行时间过长影响其他的操作.

set hive.mapred.mode = strict;  -- 开启严格模式   
set hive.mapred.mode = nonstrict; -- 开启非严格模式  最新版本默认

10.JVM重用

核心原理:重复使用已运行的container容器

        注意: 默认情况下, container资源容器只能使用一次,不能重复使用, 开启JVM重用运行container容器可以被重复使用,在hive2.x已经默认支持了此操作,.

11.推测执行

核心原理:  提前推测出拖后腿任务,为它开启一个备份任务,最终以先执行完的结果为准.

        Hadoop采用了推测执行(Speculative Execution)机制,它根据一定的法则推测出“拖后腿”的任务,并为这样的任务启动一个备份任务,让该任务与原始任务同时处理同一份数据,并最终选用最先成功运行完成任务的计算结果作为最终结果。

12.SQL优化

1.列裁剪

核心原理:只读取sql语句需要的字段,节省读取开销,提升效率

-- 6.列裁剪(只读取sql语句需要的字段,节省读取开销,提升效率)
-- 默认就是true  (在hive 2.x中无需在配置了, 直接为固定值: true)
set hive.optimize.cp=true;  

2.分区裁剪

核心原理:

1.查询SQL语句中, 能在join之前提前进行条件过滤一定要提前过滤, 不要在join后进行过滤操作.

2.如果操作的表是一张分区表, 那么建议一定要带上分区字段, 以减少扫描的数据量, 从而提升效率.

-- 7.分区裁剪
--默认为就是true (在hive 2.x中无需在配置了, 直接为固定值: true)
set hive.optimize.pruner=true; 

3.group by操作

在hive中出现数据倾斜的主要体现在两个方面:
    第一个:执行join操作(reduce join)
    第二个:执行group by 操作

配置解决方案:

方案一:  
    --(1)是否在Map端进行聚合,默认为True
    set hive.map.aggr = true;
    --(2)在Map端进行聚合操作的条目数目
    set hive.groupby.mapaggr.checkinterval = 100000;

方案二:  官方称为 负载均衡
--(3)有数据倾斜的时候进行负载均衡(默认是false)
set hive.groupby.skewindata = true;
    第一个MR Job中,Map的输出结果会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的Group By Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;
	第二个MR Job再根据预处理的数据结果按照Group By Key分布到Reduce中(这个过程可以保证相同的Group By Key被分布到同一个Reduce中),最后完成最终的聚合操作。

4.count(distinct)

核心原理:大任务的时候count(distinct)默认一个MapReduce程序,运行非常慢,拆分成两个任务去执行(先group by分组再count统计)提高效率.

优化

-- count(distinct)优化
set hive.optimize.countdistinct; -- 默认就是true
set hive.optimize.countdistinct = true;
/*
SELECT count(DISTINCT id) FROM 大表;
结果:
SELECT count(id) FROM (SELECT id FROM 大表 GROUP BY id) a;
*/
select count(distinct devicetype) from device1;
select count(devicetype) from (select devicetype from device1 group by devicetype) a;
-- 注意: 小表拆分两个mr反而效率低,以后大表的时候才会真正提升效率

5.笛卡尔积

尽量避免出现笛卡尔积的方案:

  • 避免在两表join的时候不加on条件,或无效的on条件.
  • 关联条件不要放置在where语句, 因为底层先产生笛卡尔积然后基于where进行过滤 , 建议放置on条件上
  • 如果实际开发中无法确定表与表关联条件,建议与数据管理者重新对接, 避免出现问题.

13.查看explain执行计划

        使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的。帮助我们更好地了解底层原理,进行hive调优及排查数据倾斜等问题.

14.设置Hive参数

  • 优先级

        set参数声明  >  启动服务命令行   >  配置文件
        注意: hive配置文件  >  hadoop配置文件

  • 作用域

        set参数声明  <  启动服务命令行   < 配置文件

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值