Spark学习笔记(10)---Shuffle调优
Shuffle调优
目录
调节Map端内存缓冲与Reduce端内存占比
- 问题
默认情况下,shuffle的map task,输出到磁盘文件的时候,统一都会先写入每个task自己关联的一个内存缓冲区。这个缓冲区大小,默认是32kb。
每一次,当内存缓冲区满溢之后,才会进行spill操作,溢写操作,溢写到磁盘文件中去。
reduce端task,在拉取到数据之后,会用HashMap的数据格式,来对各个key对应的values进行汇聚。在进行汇聚、聚合等操作的时候,实际上,使用的就是自己对应的executor的内存,executor(jvm进程,堆),默认executor内存中划分给reduce task进行聚合的比例,是0.2。
问题来了,因为比例是0.2,所以,理论上,很有可能会出现,拉取过来的数据很多,那么在内存中,放不下;这个时候,默认的行为,就是说,将在内存放不下的数据,都spill(溢写)到磁盘文件中去。
- 调优
spark.shuffle.file.buffer
spark.shuffle.memoryFraction
在Spark UI或者是Yarn任务调度界面,如果发现shuffle过程中磁盘的write和read很大。这个时候,就意味着最好调节一些shuffle的参数。首先当然是考虑开启map端输出文件合并机制。
调节的时候的原则。spark.shuffle.file.buffer,每次扩大一倍,然后看看效果,64,128;spark.shuffle.memoryFraction,每次提高0.1,看看效果。
spark.shuffle.sort.bypassMergeThreshold
这个配置的默认值是200,用于设置在Reducer的partition数目少于多少的时候,Sort Based Shuffle内部不使用Merge Sort的方式处理数据,而是直接将每个partition写入单独的文件。这个方式和Hash Based的方式是类似的,区别就是在最后这些文件还是会合并成一个单独的文件,
并通过一个index索引文件来标记不同partition的位置信息。从Reducer看来,数据文件和索引文件的格式和内部是否做过Merge Sort是完全相同的。
这个可以看做SortBased Shuffle在Shuffle量比较小的时候对于Hash Based Shuffle的一种折衷。当然了它和Hash Based Shuffle一样,也存在同时打开文件过多导致内存占用增加的问题。因此如果GC比较严重或者内存比较紧张,可以适当的降低这个值。
参考资料
《北风网Spark项目实战》
github: https://github.com/yangtong123/StudySpark