目录

Spark、Hive数据倾斜的解决方案

Spark优化、Hadoop(Mapreduce+小文件)的优化

Spark join的类型

Spark中JOIN执行的5种策略

map-side-join和reduce-side-join的区别

Spark里hash shuffle和sort shuffle


Spark、Hive数据倾斜的解决方案

适用场景                                       

Spark

Hive                                  

Hive原因                        

提高shuffle操作并行度

详解:在对RDD执行shuffle算子时,给shuffle算子传入一个参数,比如reduceByKey(1000),该参数就设置了这个shuffle算子执行时shuffle read task的数量,即spark.sql.shuffle.partitions.

做好分区。(分桶用于采样)

数据分布不均匀

合理设置map个数和reduce个数

聚合类的shuffle操作导致的数据倾斜

两阶段聚合(局部聚合+全局聚合)

详解:第一阶段聚合,给key加随机前缀,对加了随机前缀的key进行分区聚合;第二阶段聚合,将第一阶段的key的前缀去掉,再对原本的key进行聚合

开启数据倾斜时的负载均衡 

详解:set hive.groupby.skewindata=true;   就是到reduce那后对于大的reduce再进行reduce       2个MRJOB

数据分布不均匀

group by操作替换distinct操作

详解:例如用sum( ..group by)替换count(distinct)  distinct是全局的,所以导致会只有一个reduce

RDD或Sparksql里涉及到join 操作,且join操作里其中一个表为小表(几百兆、几兆)

将reduce join转为map join

详解:使用join算子进行连接操作,而使用Broadcast变量与map类算子实现join操作,完全规避shuffle。将较小RDD中的数据直接通过collect算子拉取到Driver端的内存中来,然后对其创建一个Broadcast变量,广播给其他Executor节点;
接着对另外一个RDD执行map类算子,在算子函数内,从Broadcast变量中获取较小RDD的全量数据,与当前RDD的每一条数据按照连接key进行比对,如果连接key相同的话,那么就将两个RDD的数据用你需要的方式连接起来。

map join打开 

详解:MAPJION会把小表全部读入内存中,在map阶段直接拿另外一个表的数据和内存中表数据做匹配,由于在map是进行了join操作,省去了reduce运行的效率也会高很多。

数据分布不均匀

两个大表JOIN,且只有其中一个表少数key数据分布不均,另一个均匀

采样倾斜Key并分拆join操作

详解:对RDD采样,把数据量最大的某几个Key和其他正常分布的key区分开来,把那几个key打上N以内的随机前缀,JOIN上的另一个RDD也过滤处这些Key并每个都膨胀为0-N条打上0-N前缀。正常分布的和正常分布的进行JOIN,加了前缀的和膨胀后也加了前缀的进行JOIN,最后两个JOIN UNION即可。

注意SQL中关联字段的数据类型是否一致

不同数据类型进行关联操作

两个大表JOIN且一个表均匀,另一个表不均匀,且不均匀的表是大量Key不均匀

使用随机前缀和扩容RDD进行join

详解:将有大量数据倾斜Key的RDD,每条数据加上0-100随机前缀;将另一个key分布相对较为均匀的RDD膨胀100倍,也加前缀;最后,两个处理后的RDD进行JOINji'ke

控制空值分布

详解:将为空的key转变为字符串加纯随机数,将因空值而造成倾斜的数据分布到多个reducer  (本质和开启数据倾斜时的负载均衡是一样的)

空值造成的

 

Spark优化、Hadoop(Mapreduce+小文件)的优化

Spark join的类型

  • 内连接(Inner Join):仅从输入数据集中输出匹配连接条件的记录。
  • 外连接(Outer Join):又分为左外连接、右外链接和全外连接。
  • 半连接(Semi Join):右表只用于过滤左表的数据而不出现在结果集中。保留右表的话就是left semi join 。
  • 交叉连接(Cross Join):交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行组合。交叉联接也称作笛卡尔积。

Spark中JOIN执行的5种策略

Spark提供了5种JOIN机制来执行具体的JOIN操作。该5种JOIN机制如下所示:

  • Shuffle Hash Join
  • 按照JOIN的key进行重分区,保证每个相同的JOIN key都发送到同一个分区中
  • Broadcast Hash Join
  • Map端JOIN
  • Sort Merge Join
  • 在join之前对 join key 排序
  • Cartesian Join
  • 如果 Spark 中两张参与 Join 的表没指定join key(ON 条件)那么会产生 Cartesian product join,这个 Join 得到的结果其实就是两张行数的乘积。
  • Broadcast Nested Loop Join
  • 该方式是在没有合适的JOIN机制可供选择时,最终会选择该种join策略。优先级为:Broadcast Hash Join > Sort Merge Join > Shuffle Hash Join > cartesian Join > Broadcast Nested Loop Join.
    在Cartesian 与Broadcast Nested Loop Join之间,如果是内连接,或者非等值连接,则优先选择Broadcast Nested Loop策略,当时非等值连接并且一张表可以被广播时,会选择Cartesian Join。

https://jiamaoxiang.top/2020/11/01/Spark%E7%9A%84%E4%BA%94%E7%A7%8DJOIN%E6%96%B9%E5%BC%8F%E8%A7%A3%E6%9E%90/

map-side-join和reduce-side-join的区别

reduce-side-join:所有数据根据key发送到所有reduce分区去,也就是shuffle的过程,造成大量网络及磁盘IO消耗,效率低。

map-side-join:当大表和小表JOIN的时候,实现在map端数据关联,跳过大量数据进行shuffle的过程,效率高。

Spark里hash shuffle和sort shuffle

hashshuffle优化前:有几个task就有几个文件

hashshuffle优化后:通过复用buffle来优化shuffle过程中产生小文件的数量

sort shuffle优化后:当shuffle read task的数量小于等于默认的200个,且不是聚合类的shuffle算子,就会启动bypass机制,bypass机制并没有对数据进行sort。