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

162 阅读3分钟

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

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

1.shuffle概述

在大数据场景下,数据shuffle表示了不同分区数据交换的过程,不同的shuffle策略性能差异较大。目前在各个引擎中shuffle都是优化的重点,在spark框架中,shuffle是支撑spark进行大规模复杂数据处理的基石。

2.spark 中 shuffle 过程

2.1 发展

  • Hash Shuffle:每个partition会映射到一个独立文件
  • 优化:每个partiton会映射到一个文件片段
  • Sort shuffle:每个task生成一个包含所有partition数据的文件
  • shuffle读数据:每个reduce task分别获取所有maptask生成的属于自己的片段。

shuffle 过程的触发流程:collect Action-->SubmitJob-->GetDependencies-->RegisterShuffle

Shuffle Handle的创建:Register Shuffle时做的最重要的事情是根据不同条件创建不同的shuffle Handle

2.2 shuffle Handle与Shuffle Writer的对应关系

  • BypassMergeShuffleWriter-->BypassMergeShuffleWriter
  • SerializedShuffleWriter-->UnsafeShuffleWriter
  • BaseShuffleWriter-->SortShuffleWriter

2.2.1 Write实现-BypassMergeShuffleWriter

  • 不需要排序,节省时间
  • 写操作的时候会打开大量文件
  • 类似于Hash Shuffle

2.2.2 Write实现UnsafeShuffleWriter

  1. 使用类似内存页存储序列化数据、
  2. 数据写入后不再反序列化
  3. 只根据partition排序Long Array
  4. 数据不移动

2.2.3 Write实现SortShuffleWriter

  • 支持combine
  • 需要combine时,使用PartitionedAppendOnlyMap,本质是一个HashTable
  • 不需要combile是partitionedPairBuffer本质是一个Array

2.2.4 Reader实现-ShuffleBlockFetchIterator

  • 区分local和remote节省网络消耗
  • 放在OOM

2.2.5 Read 实现- External Shuffle Service

ESS作为一个存在每个节点上的agent为所有shuffle Reader 提供服务,从而优化了Spark作业的资源利用率,MapTask在运行结束后可以正常退出。

2.2.6 写读都会用到的Shuffle优化使用的技术-Zero Copy

DMA:直接存储器存取,是指外部设备不通过CPU而直接与系统内存交换数据的接口技术。

  • 可堆外内存,避免JVM堆内存到堆外内存的数据拷贝。
  • CompositeByteBuf、Unpooled.wrappedBuffer、ByteBuf.slice,可以合并、包装、切分数组,避免发生内存拷贝
  • Netty使用FileRegion实现文件传输,FileRegion底层封装了FileChannel#transferT()方法,可以将文件缓冲区的数据直接传输到目标Channel,避免内核缓冲区和用户态缓冲区之间的数据拷贝。

2.3 常见问题

  • 数据存储在本地磁盘,没有备份
  • IO并发:大量RPC请求(M*R)
  • IO吞吐:随机读,写放大(3X)
  • GC频繁:影响NodeManager

2.4 Spark Shuffle优化

  • 避免shuffle:使用broadcast替代join
  • 使用可以map-side预聚合的算子
  • shuffle参数优化:修改默认并发度、忽略空的partition、修改每个task处理的文件、优化SQL、优化reducer处理数据量

2.5 Shuffle倾斜优化

  • 倾斜影响:端到端作业运行时间变长、Task OOM作业失败
  • 处理办法:提高并行度(优点:足够简单;缺点:只缓解、不根治)、Spark AQE Skew Join

2.5.1 参数调整:

spark.sql.adaptive.shuffle.targetPostShuffleInputSize;Spark.sql.files.maxPartitionBytes

2.6 Push Shuffle

  • Avg IO size大小,造成了大量的随机IO,严重影响磁盘的吞吐
  • M※R次读请求,造成大量的网络连接,影响稳定性

2.6.1 Magnet实现原理

  • spark driver组件,协调整体的shuffle操作
  • map任务的shuffle writer过程完成后,增加了一个额外的操作push-merge,将数据复制一份推到远程shuffle服务上
  • magnet shuffle service是一个强化版的ESS,将隶属于同一个shuffle partition的block,会在远程传输到magnet后被merge到一个文件中
  • reduce任务从magnet shuffle service接收合并好的shuffle数据
  • bitmap:存储已merge的mapper id防止重复merge
  • poition offset:如果本次block没有正常merge,可以恢复到上一个block的位置
  • currentMapID:标注当前正在append的block,保证不同mapper的block能依次append