大数据记录1
数据倾斜
当某个job长时间运行没有结束,可能发生了数据倾斜。
简单的讲,数据倾斜就是我们在计算数据的时候,数据的分散度不够,导致大量的数据集中到了一台或者几台机器上计算,这些数据的计算速度远远低于平均计算速度,导致整个计算过程过慢。
hive
设置map端聚合和二次group by保证reduce数据大概平均,然后再设置reduce数量减少每个reduce的数据量,尽量少用distinct,不仅设置的map端自动二次group by就失效了(distinct原理是全局排序去重),而且多个distinct也会使二次group的优化实效。 如果group by 多个字段,或者其它二次group失效的情况,可以走下方spark的解决方案,将hql分多个hql来做。
一次group可能产生某个key的数据倾斜,把这个key单独取出来,加随机前缀之后就可以打散到多个分区里。聚合出结果后再把前缀去掉再聚合一次,所以是二次group by。所以说distinct多个的话就吃不到这种优化方式了。 如果你开启hive的二次group by优化,他就会自动根据情况判断是不是需要用二次group by 但是如果distinct多个字段,这个优化机制就会失效。
并行度:设置reduce数量
分桶:设置关联字段为分桶字段
数据倾斜:
1.抽样检测分组字段,看看是否有倾斜
2.如果没有倾斜,就正常增加reduce数量,设置中间ORC+SNAPPY压缩
3.如果有倾斜,把倾斜的部分过滤出来加前缀打散处理,不倾斜的部分正常处理。
4.如果是大表join小表,大表倾斜,可以使用map端join方法,小表倾斜直接无视。
5.如果是大表join大表,某表倾斜,可以使用膨胀法处理。
具体业务具体分析:比如说两张大表关联求TopN,要用sort by limit。
c:小表:使用业务小表join大表。
select /*+ MAPJOIN(c) */ c.channel_name,count(t.requesturl) PV from ods.cms_channel c join(sele
自动选择:
set hive.auto.convert.join = true; # 默认为false
该参数为true时,Hive自动对左边的表统计量,如果是小表就加入内存,即对 小表使用Map join
hive.mapjoin.smalltable.filesize=25000000 #25mb
spark
只有当要进行join的表的大小小于spark.sql.autoBroadcastJoinThreshold(默认是10M)的时候,才会进行mapjoin
spark的配置中有一条“自动广播大小”:
//配置自动广播大小 spark.sql.autoBroadcastJoinThreshold = 10M(默认)
join的表如果小于10M,就会默认采用广播的方式进行map-join。
但是spark在读取hive表时,会根据hive元数据记录的表大小进行判断,如果元数据不准确就会发生误判断。
可以通过设置spark直接读取hdfs文件来避免:
//配置读取hdfs文件信息 spark.sql.statistics.fallBackToHdfs = ture
此外,在SQL语句中加上mapjoin的注释也可以强制指定某表进行map-join,如:
select /*+ MAPJOIN(b)*/ * from a join b
上面和下面这两种map-join的指定方式到底有什么区别我也不清楚,我推荐下面这种。
select /*+ BROADCAST(b)*/ * from a join b