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 ...
随机推荐
- bzoj 2465 小球
题目大意: 给定n个不同颜色的球,每个球都有一个分数,同时有m个瓶子,每个瓶子都有固定的容量 必须把球放到瓶子里面 计算最多能放多少个球到这些瓶子里 思路: 开始想的是费用流 超级源向每个球连一条 容 ...
- MSP430:输入捕获
在做超声模块时用到 //捕获上升沿 void Capture_Pos(void) { P2SEL |= Echo; //选择P23作为捕捉的输入端子 Timer1_A //TA1CCTL1 |=CM_ ...
- 转载:C语言的字节对齐及#pragma pack的使用
C语言的字节对齐及#pragma pack的使用 C编译器的缺省字节对齐方式(自然对界) 在缺省情况下,C编译器为每一个变量或是数据单元按其自然对界条件分配空间. 在结构中,编译器为结构的每个成员 ...
- 如何在vue项目中引入阿里巴巴的iconfont图库
1. 打开 http://www.iconfont.cn/ 2. 选择我们喜欢的图标,点击上面的小车,加入图标库,即右侧的购物车 3.点击购物车,点击下载代码 4.解压下载的文件夹,将文件夹复制到 a ...
- PCB CAM自动化程序协同业务流
最近IBM在做预审阶段的参数信息提取相关的工作,关于Gerber中的图形方面的信息数据,需由工程IT提供异步Web接口,供IBM创建任务,待Gerber图形信息分析完成后再结果将数据返回给IBM;这里 ...
- 最全的C/C++入门到进阶的书籍推荐,你需要嘛?
编程是操作性很强的一门知识,看书少不了,但只有学习和实践相结合才能起到很好的效果,一种学习方法是看视频->看书->研究书中例子->自己做些东西->交流->看书. 研究经典 ...
- redis-缓存穿透,缓存雪崩,缓存击穿,并发竞争
目录 缓存穿透 定义 解决方案 利用互斥锁 采用异步更新策略 使用布隆过滤器 空置缓存 缓存雪崩 定义 解决方案 给缓存的加一个随机失效时间 使用互斥锁 双缓存策略 缓存击穿 定义 解决方案 使用互斥 ...
- SpringBoot2.0 浅谈注解@ControllerAdvice的作用
我们都知道做项目一般都会有全局异常统一处理的类,那么这个类在Spring中可以用@ControllerAdvice来实现,费话不多说,先看代码: import org.springframework. ...
- PHPExcel读取文件日期处理,含时分秒(Thinkphp)
我们使用PHPExcel读取excel文件后发现,时间都是类似于这样的数字:41890.620138889,那么如何将它处理成我们想要的2014-09-08 14:53:00这样格式的日期呢,看代码: ...
- mybatis 中 foreach 的性能问题及调优
1.mybatis中最初的sql语句 SELECT 参数1, 参数2, 参数3 FROM 表 WHERE 条件参数1 in <foreach item="item" inde ...