本文主要关注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. Redis数据类型--string

    在Redis中支持丰富的数据类型的存储系统,包括:字符串(string),散列(hashes),列表(lists),集合(sets),有序集合(sorted sets),与范围查询,bitmaps,h ...

  2. [Luogu 3902]Increasing

    Description Input Output Sample Input 3 1 3 2 Sample Output 1 HINT 题解 由于题目要求我们求严格递增的数列,即: $$A[i]> ...

  3. Codeforces Round #402 (Div. 1)

    A题卡壳了,往离线倒着加那方面想了会儿,后来才发现方向错了,二十多分钟才过掉,过了B后做D,想法好像有点问题,最后只过两题,掉分了,差一点回紫. AC:AB Rank:173 Rating:2227- ...

  4. 【bzoj4570 scoi2016】妖怪

    题目描述 邱老师是妖怪爱好者,他有n只妖怪,每只妖怪有攻击力atk和防御力dnf两种属性.邱老师立志成为妖怪大师,于是他从真新镇出发,踏上未知的旅途,见识不同的风景. 环境对妖怪的战斗力有很大影响,在 ...

  5. [暑假的bzoj刷水记录]

    (这篇我就不信有网站来扣) 这个暑假打算刷刷题啥的 但是写博客好累啊  堆一起算了 隔一段更新一下.  7月27号之前刷的的就不写了 , 写的累 代码不贴了,可以找我要啊.. 2017.8.27upd ...

  6. 阿里云负载均衡SSL证书配置

    阿里云负载均衡SSL证书 转载请注明地址:http://www.cnblogs.com/funnyzpc/p/8908461.html 好久了呢,距上篇博客的这段时间中:考试.搬家.工作赶工.业务考察 ...

  7. c语言程序第2次作业

    (一)改错题 1.输出带框文字:在屏幕上输出以下3行信息. 错误信息1:{{uploading-image-560144.png(uploading...)} 错误原因:stdio误写为stido 错 ...

  8. C语言程序设计第六次作业--循环结构(2)

    (一)改错题 序列求和:输入一个正实数eps,计算序列部分和 1 - 1/4 + 1/7 - 1/10 + ... ,精确到最后一项的绝对值小于eps(保留6位小数). 输入输出样例: Input e ...

  9. Postgresql 创建SEQUENCE,Springboot中使用KeyHolder

    项目中使用到JdbcTemplate中的KeyHolder,代码如下: String sql = "insert into web_users(username, password, pho ...

  10. html表单验证

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...