我正在努力深入了解火花洗牌过程。当我开始阅读时,我遇到了以下几点。
Spark在完成时将Map任务(ShuffleMapTask)输出直接写入磁盘。
我想了解以下w.r.t到Hadoop MapReduce。
如果Map-Reduce和Spark都将数据写入本地磁盘,那么spark shuffle进程与Hadoop MapReduce有何不同?
由于数据在Spark中表示为RDD,为什么这些输出不会保留在节点执行程序内存中?
Hadoop MapReduce和Spark的Map任务输出有何不同?
如果有很多小的中间文件作为输出,火花如何处理网络和I / O瓶颈?
答案 0 :(得分:8)
首先,Spark无法以严格的map-reduce方式工作,除非有必要,否则map
输出不会写入磁盘。写入随机文件到磁盘。
这并不意味着shuffle之后的数据不会保留在内存中。 Spark中的随机文件主要是to avoid re-computation in case of multiple downstream actions。为什么要写入文件系统?至少有两个交错的原因:
除了正在进行的低级优化工作和实施细节之外,洗牌本身并没有什么不同。它基于相同的基本方法及其所有限制。
Hadoo地图的任务有何不同?正如Justin Pihony很好地说明的那样,不需要改组的多个转换在一个任务中被压缩在一起。由于这些操作在标准的Scala迭代器上,因此可以对各个元素进行操作。
关于网络和I / O瓶颈,这里没有灵丹妙药。虽然Spark可以减少写入磁盘的数据量或通过组合转换,内存缓存和提供转换感知工作者首选项来改组数据,但它受到与任何其他分布式框架相同的限制。
答案 1 :(得分:4)
如果Map-Reduce和Spark都将数据写入本地磁盘,那么spark shuffle进程与Hadoop MapReduce有何不同?
当你执行一个Spark应用程序时,首先是SparkContext
首先成为多个互连服务的家,DAGScheduler
,TaskScheduler
和SchedulerBackend
正在其中最重要的是。
DAGScheduler
是主要的协调器,负责将RDD谱系图(即RDD的有向无环图)转换为阶段。在执行此操作时,DAGScheduler
遍历最终RDD的父依赖项,并创建ResultStage
父项ShuffleMapStages
。
ResultStage
(大部分)是ShuffleMapStages
作为其父母的最后一个阶段。我说主要是,因为我想我可能已经看到你可以“安排”ShuffleMapStage
。
这是Spark应用于Spark作业的非常早期和第一次优化(共同创建Spark应用程序) - 执行流水线,其中多个转换连接在一起以创建单个阶段(因为它们的inter - 依赖性很窄)。这就是使Spark比Hadoop MapReduce更快的原因,因为两个或更多的转换可以逐个执行而内存中没有数据混乱。
单个阶段一直很宽,直到达到ShuffleDependency
(又名广泛依赖)。
有RDD转换会导致混乱(由于创建ShuffleDependency
)。那是Spark非常像Hadoop的MapReduce的时刻,因为它会将部分shuffle输出保存到执行器上的本地磁盘。
当Spark应用程序启动时,它会从集群管理器请求执行程序(支持三种:Spark Standalone,Apache Mesos和Hadoop YARN)。这就是SchedulerBackend
的用途 - 用于管理Spark应用程序和群集资源之间的通信。
(假设您没有使用外部随机播放管理器)
执行程序托管自己的本地BlockManager
,负责管理保存在本地硬盘驱动器上的RDD块(可能在内存中并复制)。您可以使用cache
和persist
运算符以及StorageLevel来控制RDD块持久性。您可以使用网络用户界面中的Storage
和Executors
标签来跟踪具有位置和大小的广告。
Spark本地存储数据(在执行程序上)和Hadoop MapReduce之间的区别在于:
部分结果(在计算ShuffleMapStages
之后)保存在本地硬盘驱动器而非HDFS上,而HDFS是一个分布式文件系统,保存非常昂贵。
只有一些文件保存到本地硬盘驱动器(在操作流水线后),这在Hadoop MapReduce中不会发生,它会将所有地图保存到HDFS。
让我回答以下内容:
如果有很多小的中间文件作为输出,火花如何处理网络和I / O瓶颈?
这是Spark执行计划中最棘手的部分,很大程度上取决于改组的范围。如果您只使用本地数据(单台机器上的多个执行程序),您将看不到数据流量,因为数据已经存在。
如果需要数据shuffle,执行者将在彼此之间发送数据,这将增加流量。
只是详细说明Spark应用程序中节点之间的流量。
Broadcast variables是从驱动程序向执行程序发送数据的方法。
Accumulators是从执行程序向驱动程序发送数据的方法。
collect之类的运算符会将执行程序中的所有远程块都拉到驱动程序中。
P.S。是的,数字和图表会帮助......在某些方面工作。 Upvote让我受到启发:)