问题1. 什么时候进行Shuffle的fetch操作? Shuffle是一边Mapper的map操作同时进行Reducer端的Shuffle和Reduce操作吗?
错误的观点:
Spark是一边Mapper一边Shuffle,而Hadoop的MapReduce是先完成Mapper然后才开始Reducer的Shuffle
正确观点:
Spark的Jon是按照Stage线性执行的,前面的Stage必须执行完成才能够执行后面的Reducer的Shuffle过程,为了更好的保证血缘关系,
重新计算丢失数据;Stage内部最大化的Pipline,并且这个pipline,f(records)函数f作用于集合中的每一条记录,每次只作用于一条记录
补充说明:
Spark的Shuffle是边拉取数据边进行Aggregate操作的(hadoop不是这样的),其实与HadoopMR相比其优势确实实在速度上,
但是也会导致一些算法不好实现,例如求平均值(但是Spark帮你内置了这些算子)
问题2. Shuffle fetch过来的数据到底放在了哪里?
1. 抓过来的数据首先肯定是放在Reducer端的内存缓存区中的(Spark曾经有版本要求只放在内存缓存中,数据结构类似于HashMap(AppendOnlyMap)
显然特别消耗内存和极易出现OOM,同时也从Reducer端极大的限制了Spark集群的规模),
2. 现在的实现都是内存+磁盘的方式(数据结构使用ExternalAppendOnlyMap),
当然也可以通过Spark.shuffle.spill=false来设置只能使用内存。
使用ExternalAppendOnlyMap的方式时候如果内存使用达到一定临界值,
会首先尝试在内存中扩大ExternalAppendOnlyMap(内部有实现算法),如果不能扩容的话才会spill到磁盘。
问题3. Shuffle的数据在Mapper端如何存储,在Reducer端又是如何知道数据具体在哪里的?
在Spark的实现中每一个Stage(里面是ShuffleMapTask)中的Task在Stage的最后一个RDD上一定会注册给Driver上的MapOutputTrackerMaster,
Mapper通过和MapOutputTrackerMaster来汇报ShuffleMapTask具体输出数据的位置(具体的输出文件及其内容和Reducer有关的),
Reducer是向Driver中的MapOutputTrackerMaster请求数据的元数据,然后和Mapper所在的Executor进行通信。
问题4. 仅仅从HashShuffle的角度将,我们在Shuffle的时候到底可以产生出多少Mapper端的中间件?
例如说: 有M个Mapper,有R个Reducer,有C个Core,那么在最原始的Hash Shuffle中可以产生多少个Mapper中的中间文件?
答案是: 在没有consilidation机制的情况下会产生M*R个中间文件
例如在实际生产环境下有E个Excutors(例如100个),每个Excutor有C个Core(例如10个),同时有R个Reducer。有consilidation机制的情况下产生多少个Mapper端的中间文件呢?是否可以回答E*C*R个临时文件呢?
有consilidation机制的情况下第一个问题会产生E*C*R个文件吗?不一定!这取决于一个越来越重要的配置参数”spark.task.cpus”(这个参数决定了运行Spark的每个Task需要多少个Cores,默认情况下是1个),假设”spark.task.cpus”为T,那么第一个问题的答案是:实际可用Cores的个数C/T * R 。
第二个问题的答案是E*C/T*R 如何理解Consolidation机制,你可以认为是文件池的复用。
问题5. Spark中Sorted-BasedShuffle数据默认的排序算法是什么?好处是什么?
Spark中Sorted-Based Shuffle在Mapper端是进行排序的,包括Partition的排序和每个Partition内部元素进行排序,
但是在Reducer端没有进行排序,所以JOb的结果默认情况下是不排序的,
Sorted-Based Shuffle采用Tim-Sort排序算法,好处是可以极为高效的使用Mapper端的排序成果完成全局排序.
问题6. Spark中Tungsetn-Sort Shuffle在Mapper中会对内部元素进行排序吗?
Tungsten-Sort Shuffle 在Mapper中不会对内部元素进行排序(只是对partition进行排序),
(思考排序会发生在什么时候,是在buffer spill到磁盘的时候,不是发生在进入buffer的是时候),
原因是Tungsten-Sort Shuffle是自己管理的二进制序列化后的数据。
Tungsten-Sort Shuffle 什么时候会退化成为Sorted-BasedShuffle:
在有Aggregate操作的时候或者Mapper端输出partitions高于16777216或record大于128M等的时候,
原因是Tungsten-SortShuffle是自己管理二进制序列化后的数据,以及数组指针管理范围等。(还和序列化器有关系)