本文主要关注ShuffledRDD的Shuffle Read是如何从其他的node上读取数据的。

上文讲到了获取如何获取的策略都在org.apache.spark.storage.BlockFetcherIterator.BasicBlockFetcherIterator#splitLocalRemoteBlocks中。可以见注释。

    protected def splitLocalRemoteBlocks(): ArrayBuffer[FetchRequest] = {
// Make remote requests at most maxBytesInFlight / 5 in length; the reason to keep them
// smaller than maxBytesInFlight is to allow multiple, parallel fetches from up to 5
// nodes, rather than blocking on reading output from one node.
// 为了快速的得到数据,每次都会启动5个线程去最多5个node上取数据;
// 每次请求的数据不会超过spark.reducer.maxMbInFlight(默认值为48MB) / 5。
// 这样做的原因有几个:
// 1. 避免占用目标机器的过多带宽,在千兆网卡为主流的今天,带宽还是比较重要的。
// 如果一个连接将要占用48M的带宽,这个Network IO可能会成为瓶颈。
// 2. 请求数据可以平行化,这样请求数据的时间可以大大减少。请求数据的总时间就是那个请求最长的。
// 如果不是并行请求,那么总时间将是所有的请求时间之和。
// 而设置spark.reducer.maxMbInFlight,也是为了不要占用过多的内存
val targetRequestSize = math.max(maxBytesInFlight / 5, 1L)
logInfo("maxBytesInFlight: " + maxBytesInFlight + ", targetRequestSize: " + targetRequestSize) // Split local and remote blocks. Remote blocks are further split into FetchRequests of size
// at most maxBytesInFlight in order to limit the amount of data in flight.
val remoteRequests = new ArrayBuffer[FetchRequest]
var totalBlocks = 0
for ((address, blockInfos) <- blocksByAddress) { // address实际上是executor_id
totalBlocks += blockInfos.size
if (address == blockManagerId) { //数据在本地,那么直接走local read
// Filter out zero-sized blocks
localBlocksToFetch ++= blockInfos.filter(_._2 != 0).map(_._1)
_numBlocksToFetch += localBlocksToFetch.size
} else {
val iterator = blockInfos.iterator
var curRequestSize = 0L
var curBlocks = new ArrayBuffer[(BlockId, Long)]
while (iterator.hasNext) {
// blockId 是org.apache.spark.storage.ShuffleBlockId,
// 格式:"shuffle_" + shuffleId + "_" + mapId + "_" + reduceId
val (blockId, size) = iterator.next()
// Skip empty blocks
if (size > 0) { //过滤掉为大小为0的文件
curBlocks += ((blockId, size))
remoteBlocksToFetch += blockId
_numBlocksToFetch += 1
curRequestSize += size
} else if (size < 0) {
throw new BlockException(blockId, "Negative block size " + size)
}
if (curRequestSize >= targetRequestSize) { // 避免一次请求的数据量过大
// Add this FetchRequest
remoteRequests += new FetchRequest(address, curBlocks)
curBlocks = new ArrayBuffer[(BlockId, Long)]
logDebug(s"Creating fetch request of $curRequestSize at $address")
curRequestSize = 0
}
}
// Add in the final request
if (!curBlocks.isEmpty) { // 将剩余的请求放到最后一个request中。
remoteRequests += new FetchRequest(address, curBlocks)
}
}
}
logInfo("Getting " + _numBlocksToFetch + " non-empty blocks out of " +
totalBlocks + " blocks")
remoteRequests
}

Spark技术内幕: Shuffle详解(二)的更多相关文章

  1. Spark技术内幕: Shuffle详解(一)

    通过上面一系列文章,我们知道在集群启动时,在Standalone模式下,Worker会向Master注册,使得Master可以感知进而管理整个集群:Master通过借助ZK,可以简单的实现HA:而应用 ...

  2. Spark技术内幕: Shuffle详解(三)

    前两篇文章写了Shuffle Read的一些实现细节.但是要想彻底理清楚这里边的实现逻辑,还是需要更多篇幅的:本篇开始,将按照Job的执行顺序,来讲解Shuffle.即,结果数据(ShuffleMap ...

  3. [Spark内核] 第36课:TaskScheduler内幕天机解密:Spark shell案例运行日志详解、TaskScheduler和SchedulerBackend、FIFO与FAIR、Task运行时本地性算法详解等

    本課主題 通过 Spark-shell 窥探程序运行时的状况 TaskScheduler 与 SchedulerBackend 之间的关系 FIFO 与 FAIR 两种调度模式彻底解密 Task 数据 ...

  4. Spark技术内幕:Stage划分及提交源码分析

    http://blog.csdn.net/anzhsoft/article/details/39859463 当触发一个RDD的action后,以count为例,调用关系如下: org.apache. ...

  5. 前端技术之_CSS详解第一天

    前端技术之_CSS详解第一天 一html部分 略.... 二.列表 列表有3种 2.1 无序列表 无序列表,用来表示一个列表的语义,并且每个项目和每个项目之间,是不分先后的. ul就是英语unorde ...

  6. Spark技术内幕: Task向Executor提交的源码解析

    在上文<Spark技术内幕:Stage划分及提交源码分析>中,我们分析了Stage的生成和提交.但是Stage的提交,只是DAGScheduler完成了对DAG的划分,生成了一个计算拓扑, ...

  7. 前端技术之_CSS详解第三天

    前端技术之_CSS详解第三天 二.权重问题深入 2.1 同一个标签,携带了多个类名,有冲突: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 ...

  8. 前端技术之_CSS详解第四天

    前端技术之_CSS详解第四天 一.第三天的小总结 盒模型box model,什么是盒子? 所有的标签都是盒子.无论是div.span.a都是盒子.图片.表单元素一律看做文本. 盒模型有哪些组成: wi ...

  9. 前端技术之_CSS详解第五天

    前端技术之_CSS详解第五天 一.行高和字号 1.1 行高 CSS中,所有的行,都有行高.盒模型的padding,绝对不是直接作用在文字上的,而是作用在“行”上的. <!DOCTYPE html ...

随机推荐

  1. 2015 多校联赛 ——HDU5402(模拟)

    For each test case, in the first line, you should print the maximum sum. In the next line you should ...

  2. HDU 4641 K-string

    Description Given a string S. K-string is the sub-string of S and it appear in the S at least K time ...

  3. Linux 基本概念和操作

    我们在使用Linux时,不是直接和系统打交道,而是通过shell的中间程序.在图形界面下为了实现窗口的输入和输出,linux系统为我们提供了终端模拟器Terminal,常见的终端模拟器有 gnome- ...

  4. Centos下出现read-only file system 的解决办法

    Centos下出现这种情况说明磁盘只能读不能写,出现这种情况一般是因为不正常的关机或者硬盘损坏导致磁盘挂载出现问题. 本萌新也遇到了这个问题,尝试了各种命令都不行,最后用了mount -o remou ...

  5. C语言程序设计第二次作业--顺序结构

    C语言程序设计第二次作业--顺序结构 1.输出带框文字:在屏幕上输出以下3行信息. ************* Welcome ************* 源程序 #include <stido ...

  6. 阿里2019实习内推,五轮技术面+一轮HR面,Java岗面经

    在牛客网上获取到很多知识和信息,现在反馈一波,希望能对广大找实习的同学有所帮助. 个人情况:EE方向渣硕,二月末内推了阿里集团某部门Java岗,约三周完成了所有面试. 面经如下: 一面 (简历评估): ...

  7. IOS UITextView支持输入、复制、粘贴、剪切自定义表情

    UITextView是ios的富文本编辑控件,除了文字还可以插入图片等.今天主要介绍一下UITextView对自定义表情的处理. 1.首先识别出文本中的表情文本,然后在对应的位置插入NSTextAtt ...

  8. IOS charles抓包HTTP

    charles通常用来截取本地的网络封包,但也可以用它来截取其他设备上的网络请求.本篇以IOS为例,讲解如何进行相应的操作. 1.charles上的设置 要截取iphone上的网络请求,我们要先将ch ...

  9. 重构:从Promise到Async/Await

    摘要: 夸张点说,技术的发展与历史一样,顺之者昌,逆之者亡.JS开发者们,赶紧拥抱Async/Await吧! GitHub仓库: Fundebug/promise-asyncawait 早在半年多之前 ...

  10. 利用mybatis-generator自动生成数据持久化的代码

    MyBatis生成器简介 MyBatis Generator(MBG)是MyBatis MyBatis 和iBATIS的代码生成器.它将生成所有版本的MyBatis的代码,以及版本2.2.0之后的iB ...