spark2原理分析-RDD的shuffle简介

2023-10-18 02:10

本文主要是介绍spark2原理分析-RDD的shuffle简介,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

概述

本文介绍RDD的Shuffle原理,并分析shuffle过程的实现。

RDD Shuffle简介

spark的某些操作会触发被称为shuffle的事件。shuffle是Spark重新分配数据的机制,它可以对数据进行分组,该操作可以跨不同分区。该操作通常会在不同的执行器(executor)和主机之间复制数据,这使shuffle成为复杂且非常消耗资源的操作。

Shuffle背景

为了理解shuffle过程,我们可以拿reduceByKey操作进行举例。reduceByKey操作会产生一个新的RDD,其中单个键的所有值都组合成一个元组(tuple) - 对key和与该key关联的所有值执行reduce函数的结果。挑战在于,并非单个key的所有值都必须位于同一个分区,甚至是同一个机器上,但它们必须能够被定位到才能计算结果。

在Spark中,数据通常不跨分区分布,以便特定操作能够访问到必要位置。

在计算过程中,单个任务将在单个分区上运行 - 因此,要组织单个reduceByKey reduce任务执行的所有数据,Spark需要执行all-to-all的操作。Spark必须从所有分区读取以查找所有key的所有值,然后将各个值组合在一起以计算每个key的最终结果 - 这个过程称为shuffle。

虽然新shuffle数据的每个分区中的元素集是确定的,且分区本身的顺序也是确定的,但分区中的数据的顺序是不确定的。如果在shuffle后希望得到特定顺序的数据,则可以使用:

  • 在mapPartitions使用例如.sorted对每个分区进行排序
  • repartitionAndSortWithinPartitions在同时重新分区的同时有效地对分区进行排序
  • sortBy来创建一个全局排序的RDD

可能导致shuffle的操作包括以下几种:

  • 重新分区(repartition)操作,例如: repartition和 coalesce。
  • ByKey操作(计数除外),例如:如groupByKey和reduceByKey
  • 联合(join)操作,例如:cogroup和join。

shuffle对性能的影响

shuffle操作十分昂贵(消耗性能和资源),因为它包括:磁盘I/O,数据序列号,网络I/O等操作。为了对数进行shuffle,Spark创建了一个任务集,map任务负责组织数据,reduce任务负责对数据进行聚合。这两个术语来自MapReduce,但与Spark的map和reduce操作并没有直接关系。

在内部,各个map任务的结果会保留在内存中,直到它们不再合适(fit)。然后,这些结果基于目标分区进行排序并写入单个文件。reduce任务读取相关的排好序的数据块。

某些shuffle操作会消耗大量的堆内存,因为它们使用内存中的数据结构来在传输记录之前或之后组织记录。具体来说,reduceByKey和aggregateByKey在map端创建这些结构,并且’ByKey操作在reduce端生成这些结构。当数据不适合内存时,Spark会将这些写入到磁盘,从而导致磁盘I / O的额外开销和垃圾收集的增加。

Shuffle还会在磁盘上生成大量中间文件。从Spark 1.3开始,这些文件将被保留,直到对应的RDD不再被使用,且被垃圾回收。这样做是为了在重新计算谱系时不需要重新创建shuffle文件。如果应用程序保留对这些RDD的引用或GC不经常启动,则垃圾收集可能仅在很长一段时间后才会发生。这意味着长时间运行的Spark作业可能会占用大量磁盘空间。配置Spark上下文时,spark.local.dir配置参数指定临时存储目录。

可以通过调整各种配置参数来调整shuffle行为。具体的配置将会在实战部分讲到。

注:以上两端来自官方文档对shuffle过程的说明。

理解shuffle过程

从以上分析我们可以看出,分区之间的物理数据的搬迁被称为shuffling。当需要构建新的RDD时,为了构建新的分区需要整合多个分区的数据,就会发生shuffling。例如:当通过key对成员进行分组时,Spark可能会扫描所有分区,来发现具有相同key的元素,然后在物理上对这些数据进行分组。

从以下图中可以看出具体shuffling过程:
在这里插入图片描述
上图是《spark in action》中的例子图。

上图是一个通过key来聚合数据的例子,开始的时候各个key的数据分布在不同的Spark节点上。先进行transform过程,转换过程是在各个数据的分区上进行,聚合过程需要从不同节点的分区上获取数据,此时将会发生shuffling。

注意:关于shuffle的详细代码实现,还会有文章专门进行讲解。

参考资料

  • spark官方文档

这篇关于spark2原理分析-RDD的shuffle简介的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/229511

相关文章

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

Android Mainline基础简介

《AndroidMainline基础简介》AndroidMainline是通过模块化更新Android核心组件的框架,可能提高安全性,本文给大家介绍AndroidMainline基础简介,感兴趣的朋... 目录关键要点什么是 android Mainline?Android Mainline 的工作原理关键

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

C#中async await异步关键字用法和异步的底层原理全解析

《C#中asyncawait异步关键字用法和异步的底层原理全解析》:本文主要介绍C#中asyncawait异步关键字用法和异步的底层原理全解析,本文给大家介绍的非常详细,对大家的学习或工作具有一... 目录C#异步编程一、异步编程基础二、异步方法的工作原理三、代码示例四、编译后的底层实现五、总结C#异步编程

Python 迭代器和生成器概念及场景分析

《Python迭代器和生成器概念及场景分析》yield是Python中实现惰性计算和协程的核心工具,结合send()、throw()、close()等方法,能够构建高效、灵活的数据流和控制流模型,这... 目录迭代器的介绍自定义迭代器省略的迭代器生产器的介绍yield的普通用法yield的高级用法yidle

Go 语言中的select语句详解及工作原理

《Go语言中的select语句详解及工作原理》在Go语言中,select语句是用于处理多个通道(channel)操作的一种控制结构,它类似于switch语句,本文给大家介绍Go语言中的select语... 目录Go 语言中的 select 是做什么的基本功能语法工作原理示例示例 1:监听多个通道示例 2:带

鸿蒙中@State的原理使用详解(HarmonyOS 5)

《鸿蒙中@State的原理使用详解(HarmonyOS5)》@State是HarmonyOSArkTS框架中用于管理组件状态的核心装饰器,其核心作用是实现数据驱动UI的响应式编程模式,本文给大家介绍... 目录一、@State在鸿蒙中是做什么的?二、@Spythontate的基本原理1. 依赖关系的收集2.

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序

kotlin中const 和val的区别及使用场景分析

《kotlin中const和val的区别及使用场景分析》在Kotlin中,const和val都是用来声明常量的,但它们的使用场景和功能有所不同,下面给大家介绍kotlin中const和val的区别,... 目录kotlin中const 和val的区别1. val:2. const:二 代码示例1 Java

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、