spark3.0教程:RDD并行度和分区方式(通过textFile方式生成的rdd)

sc.textFile 默认并行度

详见 spark3.0教程:sc.textFile源码分析、默认并行度(本地开发环境)

设置数量

val file: RDD[String] = sc.textFile("data/1.txt",2)

说明:

  • 参数 2 是最小分区数,实际的分区数量,可能会大于 2 个

验证 最小分区数

准备数据文件

在工程下创建 data 文件夹

在该文件夹下创建 1.txt

内容:

1
2
3

代码

val sparConf = new SparkConf().setMaster("local[*]").setAppName("WordCount")
val sc = new SparkContext(sparConf)

val file: RDD[String] = sc.textFile("data/1.txt",2)
file.saveAsTextFile("res")

sc.stop()

结果

  • 生成 3个分区 文件,与指定的 不同

  • 结果文件的换行符是:\n

分区数的计算方式

源码:

def textFile(
  path: String,
  minPartitions: Int = defaultMinPartitions): RDD[String] = withScope {
assertNotStopped()
hadoopFile(path, classOf[TextInputFormat], classOf[LongWritable], classOf[Text],
  minPartitions).map(pair => pair._2.toString).setName(path)
}

关键类:TextInputFormat,查看该类源码,可知是 hadoop 中的类,即:用 hadoop 方式读取文件

查找其父类:FileInputFormat的 getSplits(),关键代码如下:

long goalSize = totalSize / (long)(numSplits == 0 ? 1 : numSplits);

说明:

  • totalSize:读取文件的字节数
  • numSplits:指定的分区数
  • goalSize:每个分区存放的字节数。

文件的总字节数

文件的总字节数是 7 (有看不见的 \r\n)

goalSize计算过程

FileInputFormat 的 getSplits(),第 220 行代码

文件的总字节数是 7 ,所以:

goalSize=7/2=3(小数舍去)

即:每个分区文件的长度是 3 个字节

分区文件计算过程

FileInputFormat 的 getSplits(),第 251 行代码

第一个分区文件:

第二个分区文件:

第三个分区文件:

分区内容的分配方式

文件长度 7 个字节,内容如下:

1\r\n
2\r\n
3
  1. spark一行一行读取文件(与hadoop相同),与字节数无关

  2. 分区时,根据 偏移量 计算

    1. 0号分区文件的偏移量:[0,3] (每个分区文件的长度是 3 个字节),0号分区内容理论上是:1\r\n2,由于读到了 第二行,将会将整个第二行读完,所以最终内容是 1\r\n2\r\n
    2. 1号分区文件的偏移量:[3,6],读取过的偏移量不会在读取,所以不包括0号分区文件的内容,1号分区文件内容是:3
    3. 2号分区文件的偏移量:[6,7] (一共只有7个字节,所以最后一个是7)。由于已经读取完,所以是空的文件

原文出处:/show_1IX1J0J944oV.html