一、什么是shuffle?(WHAT)
shuffle 在 Spark 中表示 map task 和 reduce task 之间数据交换的过程。
二、为什么会产生 Shuffle?(WHY)
shuffle 的目的就是为了对数据进行分组,把相同的 key 放在一起。
三、什么时候会发生shuffle?(WHEN)
我们知道,Spark RDD 之间的关系分为窄依赖(父 RDD 和子 RDD 分区是一对一的关系)和宽依赖(父 RDD 和子 RDD 分区是一对多的关系)。
宽依赖也叫做 shuffle 依赖,所以说,发生宽依赖必然会发生 Shuffle,也就是宽依赖算子必然会发生 Shuffle 操作。而 shuffle 也是划分 Stage 的依据。
四、shuffle 的发生过程(HOW)

1. Map阶段
2. Shuffle Write
3. Shuffle Read
拉取的数据首先会放到内存中,然后进行数据处理,并写入相应的位置。如果 spark.shuffle.spilis=false,则处理后的数据将使用 AppendOnlyMap 仅写入内存中;否则,处理后的数据将使用 ExternalAppendOnlyMap 写入内存和磁盘。
五、什么是 ESS?(WHAT)
4. Reduce阶段
六、Spark ESS
1. 修改 yarn-site.xml
yarn-site.xml 中新增如下属性:
<property>
<name>yarn.nodemanager.aux-servicesname>
<value>spark_shufflevalue>
property>
<property>
<name>yarn.nodemanager.aux-services.spark_shuffle.classname>
<value>org.apache.spark.network.yarn.YarnShuffleServicevalue>
property>
<property>
<name>spark.shuffle.service.portname>
<value>7337value>
property>
2. 重启NodeManager
重启 NodeManager,会自动启动 ESS(External shuffle Service)。
3. 修改 spark-defaults.conf
spark.shuffle.service.enabled true
spark.shuffle.service.port 7337
八、Spark RSS
处理 Shuffle 除了可以使用 ESS,还可以使用 RSS。
ESS 的原理是 Map 任务在计算节点本地将相同 Partition 数据合并到一起;
RSS 的原理是 Map 任务将相同 Partition 数据 Push 到远端的 RSS 服务,RSS服务 将同一 partition 的数据合并。
这里就不得不提一下这个项目:Apache Celeborn,它是 RSS 的一种开源解决方案。大家可以自行去官网查看项目详情:https://celeborn.apache.org/
九、ESS 对比 RSS
ESS 和 RSS 都是为了解决 spark shuffle 过程中大量小文件读写和大量磁盘IO和网络IO,其目的都是为了优化 shuffle 过程,提高 shuffle 的效率和可靠性。
1. ESS
ESS 是一个在每个节点上运行的独立服务,它负责管理该节点上所有 Executor 生成的 Shuffle 数据。主要优势包括:
① 提高了可靠性,即使Executor进程因GC或其他原因挂掉,也不会影响Shuffle数据的可用性。
② 允许释放闲置的Executor以节省集群资源。
③ 支持动态资源分配,即Executor可以根据需要动态增加或减少。
当然它也有一些缺点:
① 脆弱的网络模型
② 低效的小文件IO
③ 缺乏Shuffle数据的Locality调度
2. RSS
RSS 是一种将 Shuffle 数据写入远端服务的解决方案。它的优点主要包括:
① 存储和计算分离,使计算节点和存储节点能够各司其职。
② 支持动态资源分配,任务完成后可以立即释放资源。
③ 能够很好地集成资源调度组件,如Kubernetes。
④ 灵活性比较大,在实际应用中,各大公司可以根据实际情况定制自己的 RSS 服务。
⑤ 减少Shuffle文件数量和读写磁盘次数,以及提供数据备份和负载均衡。
总之:
ESS 通过在每个节点上提供常驻服务来提高 Shuffle 数据的可靠性和可用性;
RSS 通过将 Shuffle 数据的存储和计算分离,进一步提高了资源利用率和系统稳定性。
选择使用 ESS 还是 RSS,或者它们的特定实现,通常取决于具体的使用场景和集群环境。
往期推荐