大数据 Shuffle 原理与实践 | 青训营笔记

64 阅读2分钟

这是我参与「第四届青训营 」笔记创作活动的的第8天

1. 概述

  1. MapReduce(MR)

  2. Shuffle 阶段:在map阶段基础上进行数据移动

  3. reduce阶段:数据处理

  4. 为什么shuffle对性能重要:M * R次网络连接;大量的数据移动;数据丢失风险;大量的排序操作;大量的序列化反序列化操作;数据压缩

2. 算子

  1. 算子分类

(1)repartition:重新分区

(2)byKey:聚合

(3)join:本身不在一起的数据放在一起

(4)distinct:特殊的bykey

  1. Spark中对shuffle的抽象——宽依赖,窄依赖

  2. 内部依赖关系(ShuffleDependency)

  • Cogroup
  • ShuffledRDD

(1)Partitioner:

两个接口:numberPartitions;getPartition

(2) Aggregator

creatCombiner:只要一个value的时候的初始化

mergeValue:合并一个value到Aggregator

mergeCombiners:合并两个Aggregator

3. 过程

  1. Hash Shuffle
  • 每个partition会映射到一个独立的文件M * R

  • 每个partition会映射到一个文件片段

  1. Sort shuffle
  • 每个task生成一个包含所有partition数据的文件,相同内容排序
  1. 读数据
  • 每个reduce task分别获取所有map task生成的属于自己的片段
  1. 过程的触发流程
graph TD
CollectAction --> SubmitJob --> GetDependencies --> RegisterShuffle
  1. Shuffle Handle 的创建

  2. BypassMergeShuffleWriter

  • 不需要排序
  • 写操作时会打开大量文件
  • 类似于HashShuffle
  1. UnsafeShuffleWriter
  • 不再反序列化
  • 使用类似内存页储存序列化数据
  • 只根据partition排序Long Array
  • 数据不移动
  1. SortShuffleWriter
  • 支持combine
  • 需要combine时,本质是HashTable
  • 不需要时,本质是array
  1. Reader实现

(1)Iterator

(2)External Shuffle Service: 区分local和remote节省网络消耗;防止OOM

  1. Zero copy

Netty Zero Copy:可堆外内存

DMA:直接存储器存取

  1. 问题
  • 没有备份
  • IO并发:大量RPC请求
  • IO吞吐:随机读
  • GC频繁
  1. Shuffle 优化
  • 避免shuffle:使用broadcast代替join

  • 使用map-side预聚合算子

  1. Shuffle 倾斜优化
  • 作业运行时间边长
  • Task OOM导致作业失败
  • 处理:提高并行度(足够简单;只缓解)
  1. Spark AQE Skew Join

将倾斜分区打散成小的子分区

4. Push Shuffle

  1. 为什么需要?
  • Avg IO size太小,造成了大量的随机IO
  • M*R次读请求,大量的网络连接
  1. 实现

  2. Magnet实现原理

  • bitmap:储存已merge的mapper id
  • position offset:可恢复到上一个block位置
  • currentMapId
  1. Magnet可靠性

  2. Cloud Shuffle Service