2.1.6、SparkEnv中创建ShuffleManager
ShuffleManager负责管理本地以及远程的block数据的shuffle操作。
ShffuleManager的创建是在SparkEnv中。
// Let the user specify short names for shuffle managers
val shortShuffleMgrNames = Map(
"sort" -> classOf[org.apache.spark.shuffle.sort.SortShuffleManager].getName,
"tungsten-sort" -> classOf[org.apache.spark.shuffle.sort.SortShuffleManager].getName)
val shuffleMgrName = conf.get("spark.shuffle.manager", "sort")
val shuffleMgrClass = shortShuffleMgrNames.getOrElse(shuffleMgrName.toLowerCase, shuffleMgrName)
//通过反射创建ShuffleManager
val shuffleManager = instantiateClass[ShuffleManager](shuffleMgrClass)
2.1.6.1、在本人的spark版本中(2.1.1)只有SortShuffleManger, 在spark1.2之前还有HashShuffleManager, 已经被移除了。
在Spark的版本的发展,ShuffleManager在不断迭代,变得越来越先进。 在Spark 1.2以前,默认的shuffle计算引擎是HashShuffleManager。该ShuffleManager而HashShuffleManager有着一个非常严重的弊端,就是会产生大量的中间磁盘文件,进而由大量的磁盘IO操作影响了性能。因此在Spark 1.2以后的版本中,默认的ShuffleManager改成了SortShuffleManager。SortShuffleManager相较于HashShuffleManager来说,有了一定的改进。主要就在于,每个Task在进行shuffle操作时,虽然也会产生较多的临时磁盘文件,但是最后会将所有的临时文件合并(merge)成一个磁盘文件,因此每个Task就只有一个磁盘文件。在下一个stage的shuffle read task拉取自己的数据时,只要根据索引读取每个磁盘文件中的部分数据即可。
接下来看看SortShuffleManger功能
注册Shuffle
通过manager注册shuffle, 同时获取一个handle用于发送任务
/**
* 注册Shuffle
* Register a shuffle with the manager and obtain a handle for it to pass to tasks.
*/
override def registerShuffle[K, V, C](
shuffleId: Int,
numMaps: Int,
dependency: ShuffleDependency[K, V, C]): ShuffleHandle = { //创建handle
if (SortShuffleWriter.shouldBypassMergeSort(SparkEnv.get.conf, dependency)) {
// If there are fewer than spark.shuffle.sort.bypassMergeThreshold partitions and we don't
// need map-side aggregation, then write numPartitions files directly and just concatenate
// them at the end. This avoids doing serialization and deserialization twice to merge
// together the spilled files, which would happen with the normal code path.
// The downside is having multiple files open at a time and thus more memory allocated to buffers. // by pass handle
new BypassMergeSortShuffleHandle[K, V](
shuffleId, numMaps, dependency.asInstanceOf[ShuffleDependency[K, V, V]])
} else if (SortShuffleManager.canUseSerializedShuffle(dependency)) {
// Otherwise, try to buffer map outputs in a serialized form, since this is more efficient:
// 序列化shuffle handle
new SerializedShuffleHandle[K, V](
shuffleId, numMaps, dependency.asInstanceOf[ShuffleDependency[K, V, V]])
} else {
// Otherwise, buffer map outputs in a deserialized form:
// 剩下就是 未序列化格式
new BaseShuffleHandle(shuffleId, numMaps, dependency)
}
}
有三种Handle : 确定使用哪种shuffle path
BypassMergeSortShuffleHandle
SerializedShuffleHandle
BaseShuffleHandle
移除shuffle
通过ShuffleBlockResolver持有的blockManager.diskBlockManager定位到数据文件和索引文件, 然后删除
/** Remove a shuffle's metadata from the ShuffleManager. */
override def unregisterShuffle(shuffleId: Int): Boolean = {
Option(numMapsForShuffle.remove(shuffleId)).foreach { numMaps =>
(0 until numMaps).foreach { mapId =>
shuffleBlockResolver.removeDataByMap(shuffleId, mapId)
}
}
true
}
getWriter
根据给定的partition,获取一个ShuffleWriter, 在executor上被map task调用
override def getWriter[K, V](
handle: ShuffleHandle,
mapId: Int,
context: TaskContext): ShuffleWriter[K, V] = { //向numMapsForShuffle中添加新的shuffleId,
numMapsForShuffle.putIfAbsent(
handle.shuffleId, handle.asInstanceOf[BaseShuffleHandle[_, _, _]].numMaps) //SparkEnv
val env = SparkEnv.get //根据ShuffleHandle匹配对应的ShuffleWriter
handle match {
case unsafeShuffleHandle: SerializedShuffleHandle[K @unchecked, V @unchecked] =>
new UnsafeShuffleWriter(
env.blockManager,
shuffleBlockResolver.asInstanceOf[IndexShuffleBlockResolver],
context.taskMemoryManager(),
unsafeShuffleHandle,
mapId,
context,
env.conf)
case bypassMergeSortHandle: BypassMergeSortShuffleHandle[K @unchecked, V @unchecked] =>
new BypassMergeSortShuffleWriter(
env.blockManager,
shuffleBlockResolver.asInstanceOf[IndexShuffleBlockResolver],
bypassMergeSortHandle,
mapId,
context,
env.conf)
case other: BaseShuffleHandle[K @unchecked, V @unchecked, _] =>
new SortShuffleWriter(shuffleBlockResolver, other, mapId, context)
}
}
getReader
创建一个BlockStoreShuffleManager 读取一个范围partition的数据, 在executor上被reduce task调用
/**
* Get a reader for a range of reduce partitions (startPartition to endPartition-1, inclusive).
* Called on executors by reduce tasks.
*/
override def getReader[K, C](
handle: ShuffleHandle,
startPartition: Int,
endPartition: Int,
context: TaskContext): ShuffleReader[K, C] = {
new BlockStoreShuffleReader(
handle.asInstanceOf[BaseShuffleHandle[K, _, C]], startPartition, endPartition, context)
}
2.1.6、SparkEnv中创建ShuffleManager的更多相关文章
- 2.1.5、SparkEnv中创建MapOutputTracker
SparkEnv中创建MapOutputTracker def registerOrLookupEndpoint( name: String, endpointCreator: => RpcEn ...
- 2.1.4、SparkEnv中创建BroadcastManager
Broadcast是分布式的数据共享,由BroadcastManager负责管理其创建或销毁.Broadcast一般用于处理共享的配置文件.通用Dataset.常用数据结构 通过SparkContex ...
- In-Memory:在内存中创建临时表和表变量
在Disk-Base数据库中,由于临时表和表变量的数据存储在tempdb中,如果系统频繁地创建和更新临时表和表变量,大量的IO操作集中在tempdb中,tempdb很可能成为系统性能的瓶颈.在SQL ...
- 【初学者指南】在ASP.NET MVC 5中创建GridView
介绍 在这篇文章中,我们将会学习如何在 ASP.NET MVC 中创建一个 gridview,就像 ASP.NET Web 表单中的 gridview 一样.服务器端和客户端有许多可用的第三方库,这些 ...
- SQL Server 在多个数据库中创建同一个存储过程(Create Same Stored Procedure in All Databases)
一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 遇到的问题(Problems) 实现代码(SQL Codes) 方法一:拼接SQL: 方法二: ...
- SAP CRM 在Web UI中创建搜索帮助
多数情况下,在Web UI为一个特定的字段提供搜索帮助需要在事务SE11中创建搜索帮助. (注:也可以通过在SE24中创建一个类并实现实现IF_BSP_WD_CUSTOM_F4_CALLBACK接口来 ...
- 详解Linux交互式shell脚本中创建对话框实例教程_linux服务器
本教程我们通过实现来讲讲Linux交互式shell脚本中创建各种各样对话框,对话框在Linux中可以友好的提示操作者,感兴趣的朋友可以参考学习一下. 当你在终端环境下安装新的软件时,你可以经常看到信息 ...
- 如何在ARM中创建Express Route
很早之前就想试试Azure的express route,但是一直没有找到合适的机会,正好有个客户需要上express route,所以最近先自己研究研究,防止在做poc的时候耗费更多时间,本次场景我们 ...
- 在powerdesigner中创建物理数据模型
物理数据模型(PDM)是以常用的DBMS(数据库管理系统)理论为基础,将CDM/LDM中所建立的现实世界模型生成相应的DBMS的SQL语言脚本.PDM叙述数据库的物理实现,是对真实数据库的描述 PDM ...
随机推荐
- imagebutton 设置了src属性的图片更换
<ImageButton android:id="@+id/mediacontroller_play_pause" android:layout_width="wr ...
- B1090 [SCOI2003]字符串折叠 区间dp
又一道区间dp,和上一篇类似,但是比他简单,这个只有两种转移方法,不是很复杂.直接判断是否为重复的串就行. 题干: Description 折叠的定义如下: . 一个字符串可以看成它自身的折叠.记作S ...
- uoj#34
模板 #include<bits/stdc++.h> #define pi acos(-1) using namespace std; ; int n, m, L, x; int r[N] ...
- 直接使用FileSystem以标准输出格式显示hadoop文件系统中的文件
package com.yoyosys.cebbank.bdap.service.mr; import java.io.IOException; import java.io.InputStream; ...
- yii2表单,用惯yii1的可以看一下,有很大不同哦
使用表单 本章节将介绍如何创建一个从用户那搜集数据的表单页.该页将显示一个包含 name 输入框和 email 输入框的表单.当搜集完这两部分信息后,页面将会显示用户输入的信息. 为了实现这个目标,除 ...
- go 学习成长之路
一.go的搭建 二.初识go 三.混个脸熟--go 四.go的语言结构 五.go的常量与变量 六.go基础数据类型 七.go 条件语句 八.go 运算符 九.go条件语句switch 十.go循环语句 ...
- 如何获得Windows聚焦壁纸0726
Windows聚焦壁纸缓存位置,绿色部分是你的用户名: (1)找到之后,一般是大于100K的 (2)将图片复制到另一个文件夹img,要用到路径 (3)在改文件夹下新建一个txt; txt文档里写:re ...
- Sum It Up -- 深搜 ---较难
每一行都是一组测试案例 第一个数字 表示总和 第二个数字表示 一共有几个可用数据 现在 按照从小到大的顺序 输出 那些数字中若干数字之和为总和的 信息 /. 很好很明显的 遍历痕迹 , ...
- hbuilder中的 http://www.w3.org/TR/html4/loose.dtd
<!-- This is the HTML 4.01 Transitional DTD, which includes presentation attributes and elements ...
- sikuli--前端自动化操作的神器
前端自动话操作应用很广泛,从网购秒杀活动实现自动化抢购,到区块链货币高频交易前端脚本编写(非合作交易所不提供api的情况下). 自动化的流派分为2类,一类是对DOM对象进行解析的,这个是主流,但是受特 ...