Hive调优

官方文档

hive官方配置文档

hive命令和参数配置

hive参数配置的意义: 开发Hive应用/调优时,不可避免地需要设定Hive的参数。设定Hive的参数可以调优HQL代码的执行效率,或帮助定位问题。然而实践中经常遇到的一个问题是,为什么我设定的参数没有起作用?这是对hive参数配置几种方式不了解导致的!

hive参数设置范围 : 配置文件参数 > 命令行参数 > set参数声明

hive参数设置优先级: set参数声明 > 命令行参数 > 配置文件参数

注意: 一般执行SQL需要指定的参数, 都是通过 set参数声明 方式进行配置,因为它属于当前会话的临时设置,断开后就失效了

1.hive数据压缩

Hive底层是运行MapReduce,所以Hive支持什么压缩格式本质上取决于MapReduce。

压缩对比

在后续可能会使用GZ(GZIP), 保证压缩后的数据更小, 同时压缩和解压的速度比较OK的,

但是大部分的选择主要会选择另一种压缩方案, snappy, 此种方案可以保证在合理的压缩比下, 拥有更高的解压缩的速度

http://google.github.io/snappy/
On a single core of a Core i7 processor in 64-bit mode, Snappy compresses at about 250 MB/sec or more and decompresses at about 500 MB/sec or more.

开启压缩

开启map输出阶段压缩可以减少job中map和Reduce task间数据传输量. 当Hive将输出写入到表中时,输出内容同样可以进行压缩。用户可以通过在查询语句或执行脚本中设置这个值为true,来开启输出结果压缩功能。


-- 创建数据库
create database hive05;
-- 使用库
use hive05;


-- 开启压缩(map阶段或者reduce阶段)
--开启hive支持中间结果的压缩方案
set hive.exec.compress.intermediate; -- 查看默认
set hive.exec.compress.intermediate=true ;
--开启hive支持最终结果压缩
set hive.exec.compress.output; -- 查看默认
set hive.exec.compress.output=true;

--开启MR的map端压缩操作
set mapreduce.map.output.compress; -- 查看默认
set mapreduce.map.output.compress=true;
--设置mapper端压缩的方案
set mapreduce.map.output.compress.codec; -- 查看默认
set mapreduce.map.output.compress.codec= org.apache.hadoop.io.compress.SnappyCodec;

-- 开启MR的reduce端的压缩方案
set mapreduce.output.fileoutputformat.compress; -- 查看默认
set mapreduce.output.fileoutputformat.compress=true;
-- 设置reduce端压缩的方案
set mapreduce.output.fileoutputformat.compress.codec; -- 查看默认
set mapreduce.output.fileoutputformat.compress.codec = org.apache.hadoop.io.compress.SnappyCodec;
--设置reduce的压缩类型
set mapreduce.output.fileoutputformat.compress.type; -- 查看默认
set mapreduce.output.fileoutputformat.compress.type=BLOCK;

2.hive数据存储[练习]

行列存储原理

行存储图解

列存储图解

行存储的特点:

查询满足条件的一整行数据的时候,列存储则需要去每个聚集的字段找到对应的每个列的值,行存储只需要找到其中一个值,其余的值都在相邻地方,所以此时行存储查询的速度更快。

列存储的特点:

因为每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量;每个字段的数据类型一定是相同的,列式存储可以针对性的设计更好的设计压缩算法。

行存储: textfile和squencefile

优点: 每行数据连续存储 select * from 表名; 查询速度相对较快
缺点: 每列类型不一致,空间利用率不高 select 列名 from 表名; 查询速度相对较慢

列存储: orc和parquet

优点: 每列数据连续存储 select 列名 from 表名; 查询速度相对较快
缺点: 因为每行数据不是连续存储 select * from 表名;查询速度相对较慢

注意: ORC文件格式的数据, 默认内置一种压缩算法:zlib , 在实际生产中一般会将ORC压缩算法替换为 snappy使用,格式为: STORED AS orc tbl (“orc.compress”=“SNAPPY”)

存储压缩比

-- 存储格式应用对比
-- 演示textfile行存储格式: 18.1 m
create table log_text (
    track_time string,
    url string,
    session_id string,
    referer string,
    ip string,
    end_user_id string,
    city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE ; -- TEXTFILE当前默认的,可以省略

-- 查询数据
select * from log_text;



-- 演示orc列存储(默认zlib): 2.78 m
create table log_orc(
track_time string,
url string,
session_id string,
referer string,
ip string,
end_user_id string,
city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS orc ;-- 默认内置一种压缩算法:ZLIB

-- 加载数据(先上传数据文件到根目录)
insert into table log_orc select * from log_text;
-- 查询数据
select * from log_orc;


-- [重点orc配合snappy]
-- 演示orc列存储(指定snappy): 3.75 m
create table log_orc_snappy(
    track_time string,
    url string,
    session_id string,
    referer string,
    ip string,
    end_user_id string,
    city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS orc tbl ("orc.compress"="SNAPPY"); -- 配合SNAPPY压缩

-- 加载数据(先上传数据文件到根目录)
insert into table log_orc_snappy select * from log_text;
-- 查询数据
select * from log_orc_snappy;

/*ORC文件格式的数据, 默认内置一种压缩算法:ZLIB , 在实际生产中一般会将ORC压缩算法替换为 snappy
格式为: STORED AS orc tbl ("orc.compress"="SNAPPY") */




-- 演示parquet压缩存储:13.09 m
create table log_parquet(
track_time string,
url string,
session_id string,
referer string,
ip string,
end_user_id string,
city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS PARQUET ;

-- 加载数据(先上传数据文件到根目录)
insert into table log_parquet select * from log_text;
-- 查询数据
select * from log_parquet;

拓展dfs -du -h

-- 查看hdfs文件大小除了去页面查看,还可以通过命令
dfs -du -h '/user/hive/warehouse/hive05.db/log_text/log.data' ;
dfs -du -h '/user/hive/warehouse/hive05.db/log_orc/000000_0' ;
dfs -du -h '/user/hive/warehouse/hive05.db/log_orc_snappy/000000_0' ;
dfs -du -h '/user/hive/warehouse/hive05.db/log_parquet/000000_0' ;

3. fetch抓取

核心点: 在执行SQL, 能不走MR, 尽量不走MR

回想, 在之前执行什么样查询的SQL的时候,没有走MR呢?

  1. 全表扫描
  2. 查询某个列数据
  3. 执行一些简答查询操作
  4. 执行limit操作

而这些操作, 没有走MR原因, 就是hive默认以及开启本地抓取的策略方案:

hive.fetch.task.conversion: 设置本地抓取策略
可选:

more (默认值): 在执行全表扫描, 查询某几个列, 进度limit操作,还有简单条件查询4种情况都不会走MR
minimal : 保证执行全表扫描以,查询某几个列,简单limit操作,3种情况可以不走MR
none : 全部的查询的SQL 都执行MR

示例:

-- 默认是more,底层自动调优
set hive.fetch.task.conversion; -- 默认结果是more
set hive.fetch.task.conversion = more;
select * from log_text; -- 不走mr
select url from log_text;-- 不走mr
select url from log_text limit 3;-- 不走mr
select url from log_text where city_id = -1;-- 不走mr

-- 可以体验下minimal模式
set hive.fetch.task.conversion = minimal;
select * from log_text;-- 不走mr
select url from log_text;-- 不走mr
select url from log_text limit 3;-- 不走mr
select url from log_text where city_id = -1;-- 走mr

-- 还可以体验下none模式
set hive.fetch.task.conversion = none;
select * from log_text;-- 走mr
select url from log_text;-- 走mr
select url from log_text limit 3;-- 走mr
select url from log_text where city_id = -1;-- 走mr

4. 本地模式

核心点:让MR能走本地模式, 尽量走本地MR(大白话: 小活能自己干就不要麻烦别人)

如何开启:

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

开启本地模式后, 在什么情况下执行本地MR: 只有当输入的数据满足以下两个特性后, 才会执行本地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(默认false,如果小数据任务进行调优开启,小任务能自己干就自己干)
set hive.exec.mode.local.auto;  -- 默认关闭
set hive.exec.mode.local.auto=false; -- 手动关闭
set hive.exec.mode.local.auto=true; -- 手动开启

--设置local mr的最大输入数据量,当输入数据量小于这个值时采用local  mr的方式,默认为134217728,即128M
set hive.exec.mode.local.auto.inputbytes.max;-- 查看
set hive.exec.mode.local.auto.inputbytes.max=134217728;

--设置local mr的最大输入文件个数,当输入文件个数小于这个值时采用local mr的方式,默认为4
set hive.exec.mode.local.auto.input.files.max;-- 查看
set hive.exec.mode.local.auto.input.files.max=4;

-- 执行sql语句
-- 没有开启本地执行24秒,开启后1.5秒
select * from log_text order by city_id desc;

-- 注意: 有的同学开启本地模式后执行上述sql语句,会报code 2...错误
-- 错误:[08S01][2] Error while processing statement: FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask
-- 如何解决? /export/server/hive/hive-env.sh  修改 export HADOOP_HEAPSIZE=2048
-- 注意: 修改完后需要重启hive服务

5. join的优化操作

思考: 在通过hive执行多表查询的SQL, 最终hive翻译的MR,是如何完成join的工作的呢?

默认的join行为, 基于reduce端的join工作

思考, 请问上述join存在哪些问题?

  1. 导致reduce的压力剧增, 所有的数据全部都打向reduce中
  2. 当有了多个reduce后, 如果某个join字段的值出现大量的重复, 会导致大量key发往同一个reduce, 从而导致数据倾斜

那么如何解决reduce端join遇到问题? 可以通过底层map 端 join实现,还可以sql语句join之前提前过滤数据或者转换数据实现

通过 map join 即可解决掉 reduce join所出现的所有的问题, 也可以这么 mapjoin有解决数据倾斜的作用

存在什么弊端:

小表数据需要存储在内存中, 随着mapTask越多, 存储在内存的小表数据份数也会越多
当这个小表数据比较大的, 可能无法放置到内存中

所以说, mapJoin有一定使用范围: 仅适用于小表 和大表 进行join的情况

大表和小表进行join:
解决方案: map join
如何开启这种操作呢?

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

在执行SQL, 应该将小表放置前面呢, 还是大表放置在前面呢,还是都可以呢 ?

(hive1) : 要求必须将小表在前大表在后 ,只有这样才可能走Map Join
(hive2): 无所谓, 谁在前, 谁在后, 没有任何的影响, hive会自动判断

大表和大表join
解决方案:
1、能在join之前过滤操作, 一定要在join前过滤, 以减少join的数据量, 从而提升效率
2、如果join字段上, 有很多的空值null值,获取其他无效数据, 这些值越多 就会导致出现数据倾斜
方案一: 提前过滤掉

select * 
from (
	select * from1 where 字段名 is not null
	) 别名1 
	join (
		select * from2 where >字段名 is not null
		) 别名2 on 关联条件;

方案二: 将null值替换为随机数, 从而减少数据倾斜影响

select * 
from (
	select case when 字段名 is null then rand() else 字段名 end  from1
	) 别名1 join (
		select case when 字段名 is null then rand() else 字段名 end  from2
		) 别名2 on 关联条件;

3、基于分桶表(大文件分为多个小文件)

6. 列裁剪

Hive在读数据的时候,可以只读取查询中所需要用到的列,而忽略其他列

例如:
假设有一个表A: a b c d e 5个字段, 请查看以下SQL
select a,b from A where a=xxx;

在这条SQL, 发现没有使用c d e 字段, 在from A表时候, 读取数据, 只需要将a列 和 b列数据读取出来即可, 不需要读取cde列字段, 这样可以减少读取的数据量, 从而提升效率

如何配置呢?

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

7. 分区裁剪

执行查询SQL的时候, 能在join之前提前进行条件过滤的操作, 一定要提前过滤, 不要在join后进行过滤操作

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

例如:

select  * from A join B where A.id=xxx;
优化后:
select * from (select * from A where id= xxx) A join B;

如何配置呢?

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

8. group by 操作

​ 执行分组操作, 翻译后的MR, 分组的字段就是k2的字段, 按照k2进行分组操作, 将相同value合并在同一个集合中, 既然分组的字段就是MR的k2, 那么分区也会按照分组字段进行分区操作, 如果某个组下数据非常的多, 可能出现出现什么问题呢?

此时有可能发生数据倾斜, 因为相同key会发往同一个reduce中

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

如何在hive中配置:
方案一:

--(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中),最后完成最终的聚合操作。

9. count(distinct)

​ 说明 : count(distinct) 在数据量比较大的情况下, 效率并不高

思考: 你知道是为什么吗?
原因如下:

请问1: 执行count操作的时候, hive翻译的MR, reduce数量是否可以有多个? 必然不会有多个, 只能有一个, 因为全局求最终结果
此时如果执行统计的时候, 需要进行去重,那么去重工作是由reduce执行去重操作, 由于reduce只有一个, 所有的数据都在一个reduce中, 此时reduce的压力比较大

希望执行去重工作可能有多个reduce一起来执行操作, 此时可以将SQL优化:
原有:
select count(distinct ip) from ip_tab;
优化:
select count(ip) from (select ip from ip_tab group by ip) tmp;

请注意: 这样的做法, 虽然会运行两个MR, 但是当数据量足够庞大的时候, 此操作绝对是值得的, 如果数据量比较少, 此操作效率更低

-- 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反而效率低,以后大表的时候才会真正提升效率

10. 笛卡尔积

​ 什么是笛卡尔积呢? 在进行join的时候, 两个表乘积之后结果就是笛卡尔积的结果

​ 比如: 一个表有5条, 一个表有3条数据, 笛卡尔积结果就有15条数据 , 笛卡尔积中有大量数据都是无用数据

​ 什么时候会产生笛卡尔积呢? 在多表join的时候, 关联条件缺少或者使用错误的关联条件以及将关联条件放置在where中都会导致笛卡尔积

在实际使用中, 建议:

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

11. 动态分区[练习]

需求: 请将下面的一个分区表数据, 拷贝到另一个分区表, 保证对应区数据放置到另一个表的对应区下

如何配置呢?
作用: 帮助一次性灌入多个分区的数据

-- 参数: 
set hive.exec.dynamic.partition.mode=nonstrict;  -- 开启非严格模式 默认为 strict(严格模式)
set hive.exec.dynamic.partition=true;  -- 开启动态分区支持, 默认就是true
	
-- 可选的参数:
set  hive.exec.max.dynamic.partitions=1000; -- 在所有执行MR的节点上,最大一共可以创建多少个动态分区。
set hive.exec.max.dynamic.partitions.pernode=100; -- 每个执行MR的节点上,最大可以创建多少个动态分区
set hive.exec.max.created.files=100000; -- 整个MR Job中,最大可以创建多少个HDFS文件

示例:

-- 回顾快速创建表
-- 1.根据score.txt数据以及格式创建表
create table score_part(
    name string,
    subject string,
    score int
)partitioned by (year string)
row format delimited fields terminated by '\t'
;
-- 2.上传score.txt到hdfs中
-- 注意: 分区表需要把文件上传到分区目录中,但是一开始没有目录,所以文件上传到任意目录后,等有了分区目录再使用load移动即可
-- 需要使用load方式生成分区目录并且插入数据
load data inpath '/score.txt' into table score_part partition (year='2022');
-- 3.hive根据元数据和分区目录中业务数据映射成表
select * from score_part;



-- 方式1: 先复制表结构再插入数据
-- 复制表结构,原来的是分区表,复制后也是分区表
create table score_part1 like score_part;
-- 不指定分区字段进行动态分区
insert into score_part1 select * from score_part;
-- 方式2: 一步到位
-- 弊端: 但是作为普通表使用了
create table score_part2 as select * from score_part;


-- 方式3: 动态分区
-- 关闭严格模式
set hive.exec.dynamic.partition.mode=nonstrict;
-- 复制表结构,原来的是分区表,复制后也是分区表
create table score_part3 like score_part;
-- 指定分区字段进行动态分区(必须是非严格模式)
insert into score_part3 partition (year) select * from score_part;

12. 如何调整map和reduce的数量

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

2>是不是保证每个map处理接近128m的文件块,就高枕无忧了?
答案也是不一定。比如有一个127m的文件,正常会用一个map去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,如果map处理的逻辑比较复杂,用一个map任务去做,肯定也比较耗时。

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

4>在什么情况下, 只能有一个reduce呢?

以下几种, 不管如何设置, 最终翻译后reduce只能有一个

  1. 执行order by操作
  2. 执行不需要group by直接聚合的操作
  3. 执行笛卡尔积
  • 如何调整mapTask数量:

    小文件场景:当input的文件都很小,把小文件进行合并归档,减少map数, 设置map数量:

    -- 每个Map最大输入大小(这个值决定了合并后文件的数量)
        set mapred.max.split.size=256000000;
    -- 一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并)
        set mapred.min.split.size.per.node=1;
    -- 一个交换机下split的至少的大小(这个值决定了多个交换机上的文件是否需要合并)
        set mapred.min.split.size.per.rack=1;
    -- 执行Map前进行小文件合并默认CombineHiveInputFormat
        set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
    

    大文件场景:当input的文件都很大,任务逻辑复杂,map执行非常慢的时候,可以考虑增加Map数,来使得每个map处理的数据量减少,从而提高任务的执行效率。

    举例:如果表a只有一个文件,大小为120M,但包含几千万的记录,如果用1个map去完成这个任务,肯定是比较耗时的,
    这种情况下,我们要考虑将这一个文件合理的拆分成多个,这样就可以用多个map任务去完成。
    set mapred.reduce.tasks=10;
    create table a_1 as select * from tab_info distribute by rand(123);
    这样会将a表的记录,随机的分散到包含10个文件的a_1表中,再用a_1代替上面sql中的a表,则会用10个map任务去完成。

  • 如何reduce的数量:

    -- 查看reduces数量
    -- 该值默认为-1,由hive自己根据任务情况进行判断。
    set mapred.reduce.tasks;
    set mapreduce.job.reduces;
    -- (1)每个Reduce处理的数据量默认是256MB左右
    set	hive.exec.reducers.bytes.per.reducer=256000000;
    -- (2)每个任务最大的reduce数,默认为1009;
    set	hive.exec.reducers.max=1009;
    

13.并行执行

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

如何配置:

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

前提:
	服务器必须有资源, 如果没有 即使支持并行, 也没有任何作用

案例:

select  * from A ....
union all
select * from B ...;

例如:
	select from (select * from A group by ...) tmp1 join (select * from B group by xxx) on ...

14. 严格模式

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

屏蔽一下操作:
1) 执行order by 不加 limit
2) 出现笛卡尔积的现象SQL
3) 查询分区表, 不带分区字段

前提: 数据量足够大, 如果数据量比较少, 严格模式对此三项内容不生效

如何配置:

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

15. JVM 重用

​ 此操作, 在hive2.x已经不需要配置了, 默认支持

jvm重用:

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

16. 推测执行

Hadoop采用了推测执行(Speculative Execution)机制,它根据一定的法则推测出“拖后腿”的任务,并为这样的任务启动一个备份任务,让该任务与原始任务同时处理同一份数据,并最终选用最先成功运行完成任务的计算结果作为最终结果。
hadoop中默认两个阶段都开启了推测执行机制。
hive本身也提供了配置项来控制reduce-side的推测执行:

set hive.mapred.reduce.tasks.speculative.execution=true;

关于调优推测执行机制,还很难给一个具体的建议。如果用户对于运行时的偏差非常敏感的话,那么可以将这些功能关闭掉。如果用户因为输入数据量很大而需要执行长时间的map或者Reduce task的话,那么启动推测执行造成的浪费是非常巨大。

17.执行计划explain

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

使用示例:explain [...]  sql查询语句;

explain sql语句: 查看执行计划的基本信息

(1)stage dependencies:各个stage之间的依赖性
包含多个stage阶段,例如 Stage-1和Stage-0,Stage-1 是根stage,Stage-0 依赖 Stage-1,
(2)stage plan:各个stage的执行计划
包含两部分: map端执行计划树和reduce端执行计划树

.mapred.reduce.tasks.speculative.execution=true;

关于调优推测执行机制,还很难给一个具体的建议。如果用户对于运行时的偏差非常敏感的话,那么可以将这些功能关闭掉。如果用户因为输入数据量很大而需要执行长时间的map或者Reduce task的话,那么启动推测执行造成的浪费是非常巨大。


## 17.执行计划explain

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

使用示例:explain […] sql查询语句;

explain sql语句: 查看执行计划的基本信息


[外链图片转存中...(img-ZI44P3yv-1700106954894)]

(1)stage dependencies:各个stage之间的依赖性
包含多个stage阶段,例如 Stage-1和Stage-0,Stage-1 是根stage,Stage-0 依赖 Stage-1,
(2)stage plan:各个stage的执行计划
包含两部分: map端执行计划树和reduce端执行计划树


[外链图片转存中...(img-BPnduCQT-1700106954896)]

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
对于Hive调优思路,可以从以下几个方面入手: 1. 数据存储和分区设计:合理的数据存储和分区设计可以提高查询性能。根据业务需求,将数据按照合适的列进行分区,这样可以减少数据扫描量。 2. 数据压缩:使用合适的压缩格式可以减小数据存储空间,并提高查询性能。例如,使用Snappy、LZO等压缩算法来减少磁盘IO和网络传输。 3. 数据倾斜处理:当某些列的值过于集中,导致某些Task处理的数据量远大于其他Task时,会导致任务执行时间不均衡。通过对倾斜键进行处理,如使用随机前缀或者进行拆分处理,可以解决数据倾斜问题。 4. 合理设置Hive参数:根据实际情况调整Hive的参数配置,以提高查询性能。常见的参数包括:hive.exec.parallel、hive.tez.container.size、hive.vectorized.execution.enabled等。 关于Hive的参数配置,下面是一些常用的参数: 1. hive.exec.parallel:设置并行执行任务的线程数,默认为1。可以根据集群资源情况适当调整,以提高任务执行效率。 2. hive.tez.container.size:设置每个Tez任务的容器大小,默认为1024(MB)。可以根据具体的任务需求和集群资源情况进行调整,以充分利用集群资源。 3. hive.vectorized.execution.enabled:启用向量化执行,可提高查询性能。默认为false,可以通过设置为true来开启向量化执行。 4. hive.optimize.sort.dynamic.partition:动态分区排序优化,默认为true。对于动态分区表,可以开启该参数以提高插入性能和查询性能。 5. hive.stats.autogather:自动收集统计信息,默认为true。开启该参数可以帮助优化查询计划,提高查询性能。 以上是一些常见的Hive调优思路和参数配置,具体的调优策略还需要根据实际情况进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

早安Naor

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值