HashShuffleManager测试shuffle阶段中间文件数量


环境:

spark 1.6.0 & 1.5.1

1.HashShuffleManager

spark2.0之后就没有HashShuffleManager了,所以使用1.6版本来测试。

spark1.1之前一直是默认HashShuffleManager。

我们知道,spark中的HashShuffleManager,进行shuffle时,会生成大量的中间结果文件,频繁的创建文件会产生大量句柄,并产生大量IO操作。影响执行效率。

此shuffle过程每个task都会产生numReducers个文件,如果一个executor有M个task,经过shuffle阶段后R个reducers。那么当前executor会产生MR个文件。如果一个节点运行E个executor,此节点上将会产生EM*R个文件。

下面我们测试一下文件数到底是不是M*R个。我们以本地测试为例。

val sparkConf = new SparkConf()
   sparkConf.setAppName(this.getClass.getName)
     .setMaster("local[2]")
     .set("spark.shuffle.manager","hash")
   val sc = new SparkContext(sparkConf)
val lines = sc.textFile("...",2)

设置spark.shuffle.manager = hash
读取文件的并行度设置为2,也就是maptask的数量等于2。

val rdd = lines.flatMap(_.split("\t")).map((_,1)).reduceByKey(_+_,3)

这里reduceByKey的shuffle并行度设置为3.

rdd.collect \\触发job
Thread.sleep(2000000) 	\\程序睡眠,查看shuffle中间文件数量,防止临时文件删除

日志信息

INFO DiskBlockManager: Created local directory at C:\Users\Administrator\AppData\Local\Temp\blockmgr-13afb58d-9521-4e71-8ebb-0d44f0e8bcb6

通过日志查看中间结果是存在了C:\Users\Administrator\AppData\Local\Temp\blockmgr-13afb58d-9521-4e71-8ebb-0d44f0e8bcb6文件夹下面。

通过windows的cmd命令查看该文件夹下有多少个文件。

C:\Users\Administrator> dir C:\Users\Administrator\AppData\Local\Temp\blockmgr-13afb58d-9521-4e71-8ebb-0d44f0e8bcb6\* /s 

shuffleFile06
可以看到有6个文件。
正好等于 mapTask数量 * reduceTask数量 = 2*3 = 6。

下面修改一个reduceTask的数量看看是否和预期一样。

val rdd = lines.flatMap(_.split("\t")).map((_,1)).reduceByKey(_+_,4)

这里修改reduceByKey的shuffle并行度为4.

在看一下文件数量。
shuffleFile06

8个文件,正好等于 2*4.

2.SortShuffleManager

如果改成 SortShuffleManager

val sparkConf = new SparkConf()
   sparkConf.setAppName(this.getClass.getName)
     .setMaster("local[2]")
     .set("spark.shuffle.manager","sort")
   val sc = new SparkContext(sparkConf)
val lines = sc.textFile("...",2)

应该是 core * maptask = 22 = 4
测试
shuffleFile06
结果显示是 4个文件 = 2
2

改成val lines = sc.textFile("…",3)
应该是 23 = 6
测试
shuffleFile06
结果显示 6个文件 = 2
3

3.HashShuffleManager + consolidateFiles

spark.shuffle.consolidateFiles这个参数在1.6版本之后被移除了
所以使用1.5.1的版本来测试

val sparkConf = new SparkConf()
sparkConf.setAppName(this.getClass.getName)
  .setMaster("local[2]")
  .set("spark.shuffle.manager","hash")   
  .set("spark.shuffle.consolidateFiles","true")  \\1.5及之前有这个参数
val sc = new SparkContext(sparkConf)

val lines = sc.textFile("...",3)

val rdd = lines.flatMap(_.split("\t")).map((_,1)).reduceByKey(_+_,5)

读取文件的并行度设置为3,也就是maptask的数量等于3.

这里reduceByKey的shuffle并行度设置为5.

开启了map端输出文件合并功能,理论上中间文件数量应该是core * R = 25 = 10
测试
shuffleFile06
结果显示 10个文件 = 2
5

修改 core数 = 3
setMaster(“local[3]”)
理论上文件数 = 3*5 = 15

测试
shuffleFile06
结果显示 15个文件 = 3*5


欢迎访问个人博客

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SparkShuffle阶段是指在数据处理过程中,将数据重新分区和排序的过程。它是Spark中非常重要的一个阶段,用于将数据从上一个阶段的任务输出到下一个阶段的任务。 在Shuffle阶段中,有两个主要的操作:shuffle write和shuffle read。 1. Shuffle Write(洗牌写入):在Mapper阶段,上一个阶段的任务将最终结果写入磁盘,并根据分区规则将数据划分到不同的分区文件中。每个分区文件对应一个Reducer任务。 2. Shuffle Read(洗牌读取):在Reducer阶段,下一个阶段的任务从上一个阶段的任务中拉取数据进行合并。这个过程涉及网络传输和数据合并操作。 Shuffle阶段的目的是为了将具有相同key的数据聚合在一起,以便后续的计算可以更高效地进行。它是Spark中性能瓶颈的一个关键点,因为涉及到大量的数据传输和磁盘IO操作。 下面是一个示例代码,演示了SparkShuffle阶段的使用: ```python # 创建SparkContext from pyspark import SparkContext sc = SparkContext("local", "Shuffle Example") # 创建RDD data = [1, 2, 3, 4, 5] rdd = sc.parallelize(data) # 在map操作中使用shuffle mapped_rdd = rdd.map(lambda x: (x % 2, x)) # 在reduceByKey操作中使用shuffle reduced_rdd = mapped_rdd.reduceByKey(lambda x, y: x + y) # 打印结果 result = reduced_rdd.collect() for key, value in result: print(key, value) # 关闭SparkContext sc.stop() ``` 这个示例中,我们首先创建了一个包含1到5的RDD。然后,在map操作中,我们使用了shuffle将数据按照奇偶数进行分区。最后,在reduceByKey操作中,我们使用了shuffle将具有相同key的数据进行合并。最终,我们打印了结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值