RDD是Spark对各种数据计算模型的统一抽象,被用于迭代计算过程以及任务输出结果的缓存读写。算法
在全部MapReduce框架中,shuffle是链接map任务和reduce任务的桥梁。shuffle性能优劣直接决定了缓存
整个计算引擎的性能和吞吐量。性能优化
MappedRDD的iterator方法网络
shuffle是全部MapReduce计算框架所必须通过的阶段,shuffle用于打通map任务的输出与reduce任务的输入,app
map任务的中间输出结果按照key值哈希后分配给某一个reduce任务。框架
目前Spark的shuffle已经作了多种性能优化,主要解决方案包括:函数
1>将map任务输出的bucket(给每一个partition的reduce)合并到同一个文件中,这解决了bucket数量很对多,可是自己数据体积不大性能
时,形成shuffle很频繁,磁盘I/O成为性能瓶颈的问题。fetch
2>map任务逐条输出计算结果,而不是一次性输出到内存中,并使用缓存及其聚合算法对中间结果进行聚合,大大减少了中间结果所占的内存大小。大数据
3>缓存溢出判断,超过大小时,将数据写入磁盘,防止内存溢出
4>reduce任务对拉取到的map任务中间结果逐条读取,而不是一次性读入内存,并在内存中使用聚合和排序,大大减小了数据占用内存
5>reduce任务将要拉取的Block按照BlockManager地址划分,而后将同一BlockManager地址中的Block累计为少许网络请求,减小网络I/O
首先理解两个概念:
bypassMergeThreshold:传递到reduce端再作merge操做的阈值。默认200
bypassMergeSort:标记是否传递到reduce端再作合并和排序
map端计算结果缓存有三种处理方式:
1.map端对计算结果在缓存中执行聚合和排序。
2.map不适用缓存,也不执行聚合和排序,直接调用spillToPartitionFiles将各个partition直接写到本身存储文件,
最后由reduce端对计算结果执行合并和排序。
3.map端对计算结果简单缓存。
在一个任务的分区数量一般不少,若是只是简单地将数据存储到Executor上。在执行reduce任务时会存在大量的网络I/O操做。
这时网络I/O将成为系统性能的瓶颈,reduce任务读取map任务的计算结果变慢,致使其余任务不得不选择分配到更远的节点。
经过在map端对计算结果在缓存中执行聚合和排序,可以节省I/O操做,进而提高系统性能。
AppendOnlyMap和SizeTrackingPairBuffer的容量均可以增加,那么数据量不大的时候不会有问题。
因为大数据处理的数据量每每都比较大,所有都放入内存内会将系统内存撑爆,Spark为了防止这个问题,
提供函数maybeSpillConllection。
wirtePartitionFile用于持久化计算结果。
1.溢出到分区文件后合并:将内存中缓存的多个partition的计算结果分别写入临时Block文件,再将这些Block文件的内容所有写入到Block输出文件中。
2.内存中排序合并:将缓存的中间计算结果按照partition分组后写入Block输出文件。
每一个map任务实际最后只会生成一个磁盘文件。
partitionedIterator 经过对集合按照指定的比较器进行比较,按照partition id分组,生成迭代器。
sendRequest方法用于远程请求中间结果。
sendRequest利用FetchRequest里封装的BlockId、size、address等信息。
调用shuffleClient的fetchBlocks方法获取其余节点上的中间结果。
fetchLocalBlock用于对本地中间计算结果的获取。
本章从迭代计算的层层剥离开始,分析了map和reduce任务的处理逻辑。