hive的数据倾斜以及优化策略(代码片段)

author author     2023-02-23     647

关键词:

1. hive的数据倾斜

介绍:只要在分布式一定有shuffle,避免不了出现数据倾斜,在混淆数据的过程中出现数据分布不均匀。比如:在MR编程中reducetask阶中的数据的大小不一致,即很多的数据集中到了一个reducetask中,hive的数据倾斜就是mapreduce的数据倾斜 maptask reducetask最后就是reducetask阶段的数据倾斜。
不会产生数据倾斜的场景
   - 不执行MapReduce程序,在hive中hive.fetch.task.conversion一共有三个可选值:
    - none:表示所有的语句都执行MR,这个参数不可用
    - minimal :表示select *、where 字段为分区字段、limit时不执行MR
    - more :select 、filter /where 、limit不执行MR
   - 聚合函数和group by一起使用的时候,在聚合函数和group by一起使用的时候,默认的MR底层在map端执行combiner,所以不会数据倾斜
会产生数据倾斜的场景
   - 聚合函数不和group by连用
   - count(distinct)
   - join 主要是reduce join会产生数据倾斜

具体场景分析:

1)join时null值过多

 以log日志为例,其中有一个字段为userid,但是userid的null值太多,在使用userid进行join时,所有的userid=null的数据都会到一个reduce中,这个reducetask数据量很大,就会产生数据倾斜。
  解决方法1

#null值不参与连接
select field1,field2,field3…
from log a left join user b on a.userid is not null and a.userid=b.
userid
union select field1,field2,field3 from log where userid is null;

  解决方法2
#将null值进行散列

select 
    * 
    from log a left join user b on 
    case when a.userid is null then concat("null",rand()) 
    else a.userid end=b.userid;

2)连接的时候两个表连接的列的类型不统一

user userid string 表一
log userid int 表二
select * from log a left join user b on a.userid=b.userid;
默认情况下,将string转化为int类型,如果string类型的userid中是无法转化为int类型,那么返回了大量的null,然后大量的null, 又会分配到同一个reducetask中,造成数据倾斜。只要确定能将string转化为int类型,就可以避免数据倾斜。

3)join端产生数据倾斜

大小表连接:大表和小表进行关联的时候,使用map端的join,在map join 时是没有数据倾斜的。其中有两个参数:
   - hive.auto.convert.join #开启map join,默认是开启的
   - hive.smalltable.filesize #在进行mapjoin时对小表大小的限制,默认是25000000byte,大概25M
大小表连接,但是小表数据量较大
  这个小表不是很大,但是超过了25000000byte;此时默认执行reducejoin,此时如果执行了reduce join就容易产生数据倾斜,如果这时小表的大小不是很大不超过100M,那么可以强制执行map join:

#强制执行map join
select
/*+mapjoin(表名)*/       #将小表强制放入内存
* from t1 join t2 on t1.field1=t2.field;

大表*大表:对其中的一个表进行过滤,将这个表转化成相对小的表,然后强制执行map端join
这里以两个表为例:
user ----30G(所有用户)
Log ----5G (当日记录的日志)

#先对log日志表进行userid  过滤:
create table temp_log as 
                    select distinct userid  from log;
#将上面的结果和user表进行关联:(获取userid表中有效的关联数据)
create table temp_user as   
select filed1, filed2,field3
                        /*+mapjoin(a)*/
                        from temp a join user b on a.userid =b.userid;
#最后,在将上面的表与log进行关联:
select filed1, filed2,field3
                        /*+mapjoin(a)*/
                    from temp_user a join Log b on a. userid =b. userid;

2. hive的优化

(1)常用优化手段:

   - 好的设计模型,在设计表的时候注意数据倾斜
   - 解决数据倾斜问题
   - 减少job数量
   - 设置合理的reduce task个数
   - 了解数据的分布情况,手动解决数据倾斜
   - 在数据量比较大的时候,尽量少用全局聚合类的操作
   - 对小文件进行合并,减少maptask个数,提高性能

(1)具体的优化方案:

   ① 如何正确的选择排序:
    - cluster by:对同一字段分桶并排序,不能和 sort by 连用
    - distribute by + sort by:分桶,保证同一字段值只存在一个结果文件当中,结合 sort by 保证 每个 reduceTask 结果有序
    - sort by:单机排序,单个 reduce 结果有序
    - order by:全局排序,缺陷是只能使用一个 reduce task
   ② 怎样做笛卡尔积:当 Hive 设定为严格模式(hive.mapred.mode=strict)时,不允许在 HQL 语句中出现笛卡尔积
解决笛卡尔积问题:http://blog.51cto.com/14048416/2338651
文章中的:6)使用随机前缀和扩容RDD进行join,有细致讲解。
   ③ 怎样写好 in/exists:

#使用left semi join.去代替in/exists:
select a.id, a.name from a where a.id in (select b.id from b);
#变化为:
selecet a.id,a.name from a left semi join b on a.id=b.id;

技术分享图片
博文:http://blog.51cto.com/14048416/2342407 其中的关于left semi join 的总结。
   ④ 合理处理maptask个数:
    Maptask个数太大:每个Maptask都要启动一个jvm进程,启动时间过长,效率低,Maptask个数太小:负载不均衡,大量作业时,容易阻塞集群。因此通常有两种手段来解决问题:
   - 减少Maptask个数,通过合并小文件实现,主要针对数据源
   - 通过设置重用jvm进程的方式,减少MapReduce程序在启动和关闭jvm进程的时间:(set mapred.job.reuse.jvm.num.tasks=5) 表示map task 重用同一个jvm.
   ⑤ 合理设置reduce task个数:
     reducer 个数的设定极大影响执行效率,这使得 Hive 怎样决定 reducer 个数成为一个关键问题,默认的在hive中只启动一个reducetask。其中有以下几个参数作为调优点:
   - hive.exec.reducers.bytes.per.reducer #reduceTask的吞吐量
   - hive.exec.reducers.max #启动的reducetask的最大值 经验之谈:0.95*(集群中 datanode 个数)
   - mapreduce.job.reduces= #设置reducetask的个数
   ⑥ 小文件合并:
     小文件过多,会给hdfs带来压力,并且会影响处理效率,可以通过合并 Map 和 Reduce 的 结果文件来消除这样的影响,以下几个参数可以作为调优点:
   - set hive.merge.mapfiles = true 在只有maptask时,任务结束时进行文件合并
   - set hive.merge.mapredfiles = false # true 时在 MapReduce 的任务结束时合并小文件
   - set hive.merge.size.per.task = 25610001000 #合并的小文件的大小
   - set mapred.max.split.size=256000000; #每个map最大分割数
   - set mapred.min.split.size.per.node=1; #一个节点上的最小split值
   - set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;,#执行map前进行小文件合并(默认开启)
   ⑦ 合理的设置分区:
   Partition 就是分区。分区通过在创建表时启用 partitioned by 实现,为了减少查询时候的数据扫描范围 提升查询性能,当数据两个比较大的时候,对经常按照某一个字段进行过滤查询的时候,就需要按照过滤字段创建分区表。
   ⑧ 合理的利用存储格式:
   创建表时,尽量使用 orc、parquet 这些列式存储格式,因为列式存储的表,每一列的数据在物理上是存储在一起的,Hive 查询时会只遍历需要列数据,大大减少处理的数据量。
   ⑨ 并行化处理
   一个hive sql语句可能转化为多个mapreduce Job,每一个job就是一个stage,这些job顺序执行,在这个client的运行日志也可以看到。但是有的时候这些任务之间并不是相互依赖的,如果集群资源允许,可以让多个并不相互依赖的stage并发执行。以下有两个参数可以调优:
    - set hive.exec.parallel=true; #开启并行
    - set hive.exec.parallel.thread.number=8; //同一个 sql 允许并行任务的最大线程数
   ⑩ 设置压缩存储
    Hive最终是因为转为MapReduce程序来执行,而MapReduce的性能瓶颈在与网络和IO,要解决性能瓶颈,最主要的就是减少数据量,对数据进行压缩是一个很好的办法。
技术分享图片

Job输出文件按照block以gzip的方式进行压缩:
set mapreduce.output.fileoutputformat.compress=true // 默认值是 false 
set mapreduce.output.fileoutputformat.compress.type=BLOCK // 默认值是 Record 
set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.GzipCodec // 默认值是 org.apache.hadoop.io.compress.DefaultCodec

map输出结果以gzip进行压缩:
set mapred.map.output.compress=true 
set mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.GzipCodec // 默认值是 org.apache.hadoop.io.compress.DefaultCodec

对hive输出结果和中间都进行压缩:
set hive.exec.compress.output=true // 默认值是 false,不压缩 
set hive.exec.compress.intermediate=true // 默认值是 false,为 true 时 MR 设置的压缩才启用

hive参数优化和数据倾斜(代码片段)

文章目录Hive数据倾斜原因:表现:解决方案:Hive调优Hive数据倾斜原因:key分布不均匀,数据重复表现:任务进度长时间维持在99%(或100%),查看任务监控页面,发现只有少量(1个或几... 查看详情

hive性能优化之计算job执行优化(代码片段)

...析优化器5谓词下推(PPD)5.1基本思想5.2基本规则6数据倾斜6.1数据倾斜的现象6.2数据倾斜的原因6.3groupBy的数据倾斜6.4Join的数据倾斜1Explain1.1功能HiveQL是一种类SQL的语言,从编程语言规范来说是一种声明式语言,用... 查看详情

hive优化笔记(代码片段)

....程序角度优化5.1熟练使用SQL提高查询5.2无效ID在关联时的数据倾斜问题5.3不同数据类型关联产生的倾斜问题5.4利用Hive对UNIONALL优化的特性5.5解决Hive对UNIONALL优化的短板消灭子查询内的COUNT(DISTINCT)&#x 查看详情

hive优化(代码片段)

...看看Hadoop的计算框架特性,在此特性下会衍生哪些问题?数据量大不是问题,数据倾斜是个问题。jobs数比较多的作业运行效率相对比较低,比如即使有几百行的表,如果多次关联多次汇总,产生十几个jobs,耗时很长。原因是mapr... 查看详情

大数据面试题----hive的调优及数据倾斜(代码片段)

...1)小表、大表Join    将key相对分散,并且数据量小的表放在join的左边,这样可以有效减少内存溢出错误发生的几率;再进一步,可以使用Group让小的维度表(1000条以下的记录条数)先进内存。在map端完成reduce。实... 查看详情

hive与优化方法(代码片段)

...章目录Hive与优化方法一、Hive概念二、Hive架构三、Hive与数据库的比较四、Hive中一些重要的概念4.1内部表和外部表4.2分区表4.3Hive排序关键字4.4Hive分桶4.5三种排序窗函数的区别4.6Hive解析MR的Reduce数量的确定4.7Hive的存储格式五、Hive... 查看详情

hive大表join空key优化(代码片段)

hive大表join空key优化如果A表中有大量c字段为null的数据。如果不对null值处理,此时,会产生数据倾斜!情形一情形二如果A表中有大量c字段为null的数据。如果不对null值处理,此时,会产生数据倾斜!情形... 查看详情

hive性能优化(代码片段)

...看看Hadoop的计算框架特性,在此特性下会衍生哪些问题?数据量大不是问题,数据倾斜是个问题。jobs数比较多的作业运行效率相对比较低,比如即使有几百行的表,如果多次关联多次汇总,产生十几个jobs,耗 查看详情

hadoop数据倾斜总结(代码片段)

在做Shuffle阶段的优化过程中,遇到了数据倾斜的问题,造成了对一些情况下优化效果不明显。主要是因为在Job完成后的所得到的Counters是整个Job的总和,优化是基于这些Counters得出的平均值,而由于数据倾斜的原... 查看详情

hive学习之路(十九)hive的数据倾斜(代码片段)

1、什么是数据倾斜?由于数据分布不均匀,造成数据大量的集中到一点,造成数据热点2、Hadoop框架的特性  A、不怕数据大,怕数据倾斜  B、Jobs数比较多的作业运行效率相对比较低,如子查询比较多  C、sum,count,max,min等... 查看详情

hive高级操作(优化,数据倾斜优化)

2019/2/21星期四hive高级操作(优化,数据倾斜优化)分区表/桶表应用,skew,map-join//见hive的基本语法行列转换hive优化hive优化思想Explain的使用经典案例(distinctcount)数据倾斜的原因操作:关键词情形后果1、Join其中一个表较小,但... 查看详情

hive优化策略

...:配置优化(hive-site.xml和hive-cli执行前配置)、表优化、hive数据倾斜解决方案。回答的时候需要,需要准确的说出具体的配置参数,准确的说出具体的配置参数,这是一个深刻的教训。配置优化1-Fetch抓取配置Fetch抓取是指,Hive中... 查看详情

实操|hive数据倾斜问题定位排查及解决(代码片段)

Hive数据倾斜怎么发现,怎么定位,怎么解决多数介绍数据倾斜的文章都是以大篇幅的理论为主,并没有给出具体的数据倾斜案例。当工作中遇到了倾斜问题,这些理论很难直接应用,导致我们面对倾斜时还是... 查看详情

大数据之hive:hive调优全方位指南(代码片段)

目录一、HiveSQL语法二、Hive性能优化三、Hive性能优化之数据倾斜专题四、HiveSQL优化十二板斧五、Hive面试题(一)六、Hive/Hadoop高频面试点集合(二)本文基本涵盖以下内容:一、HiveSQL语法hive的DDL语法对数据库的操作创建数据库:cr... 查看详情

hive数据倾斜解决思路(代码片段)

Hive数据倾斜总结发生倾斜的根本原因在于,shuffle之后,key的分布不均匀,使得大量的key集中在某个reduce节点,导致此节点过于“忙碌”,在其他节点都处理完之后,任务的结整需要等待此节点处理完,... 查看详情

hive与优化方法(代码片段)

...章目录Hive与优化方法一、Hive概念二、Hive架构三、Hive与数据库的比较四、Hive中一些重要的概念4.1内部表和外部表4.2分区表4.3Hive排序关键字4.4Hive分桶4.5三种排序窗函数的区别4.6Hive解析MR的Reduce数量的确定4.7Hive的存储格式五、Hive... 查看详情

hive优化场景七--数据倾斜--groupby倾斜

参考技术AHIVE优化场景七--数据倾斜:GROUPBY场景下的数据倾斜JOIN场景下的数据倾斜1)由于空值导致的数据倾斜问题2)由于数据类型不一致,导致的转换问题,导致的数据倾斜3)业务数据本身分布不均,导致的数据倾斜,下面4个小... 查看详情

一篇文章带你搞懂慢sql以及优化的策略(代码片段)

...么是慢SQL?二、为什么要对慢SQL进行优化?三、数据库性能1.最大数据量2.最大并发数3.查询耗时0.5秒4.具体实施四、数据库表的设计1.数据类型2.避免空值3.text类型优化五、索引优化1.索引分类2.索引优化六、SQL优化1.分批... 查看详情