Spark 源码解读03---(文件生成的)rdd的分区个数

2.3、从外部存储(文件)创建rdd的个数

  • 代码案例

    val conf = new SparkConf().setAppName("Simple Application").setMaster("local[*]")
    val sc = new SparkContext(conf)
    // 读取本地文件
    val readline = sc.textFile("input/1.txt")
    readline.collect.foreach(println)
    val par = readline.getNumPartitions
    println(s"partitions: $par")
    
  • 源码解读

    // 读取本地文件
    val readline = sc.textFile("input/1.txt")
    // 点进 textFile
    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)
      }
    /**
    textFile方法中有下面这个参数
    分区个数   minPartitions: Int = defaultMinPartitions 
    最小分区数没有指定的 就取defaultMinPartitions 
    点进 defaultMinPartitions 看看
    */
    def defaultMinPartitions: Int = math.min(defaultParallelism, 2)
    /*
    这个方法就很明显了 defaultParallelism 和 2 之间取最小值
    defaultParallelism 就是之前从集合(内存)中创建rdd中分析的是一样的,都是默认申请的核心数
    可以点进去看看
    */
      def defaultParallelism: Int = {
        assertNotStopped()
        taskScheduler.defaultParallelism
      }
    
    /**
    但是 有些时候我们会发现,实际的分区个数和我看到的不一样。那是因为 读取文件时 遵循hadoop读取文件划分原则 当总字节数/每个分区字节数的余数 
    再除以 每个分区字节数 大于0.1 将增加一个分区
    详细代码如下:
    
    // 数据划分代码
    hadoopFile(path, classOf[TextInputFormat], classOf[LongWritable], classOf[Text],
          minPartitions).map(pair => pair._2.toString).setName(path)
    
    spark  文件划分主要是调用 Hadoop 中的包
    classOf[TextInputFormat]
    TextInputFormat 进入
    */
    public class TextInputFormat extends FileInputFormat<LongWritable, Text>
      implements JobConfigurable {}
    /*
    进入父类FileInputFormat 找到 InputSplit 方法
    下面是部分代码
    */
    
    public InputSplit[] getSplits(JobConf job, int numSplits)
        throws IOException {
        Stopwatch sw = new Stopwatch().start();
        FileStatus[] files = listStatus(job);
        
        // Save the number of input files for metrics/loadgen
        job.setLong(NUM_INPUT_FILES, files.length);
        long totalSize = 0;                           // compute total size
        for (FileStatus file: files) {                // check we have valid files
          if (file.isDirectory()) {
            throw new IOException("Not a file: "+ file.getPath());
          }
          totalSize += file.getLen();
        }
    
        long goalSize = totalSize / (numSplits == 0 ? 1 : numSplits);
        long minSize = Math.max(job.getLong(org.apache.hadoop.mapreduce.lib.input.
          FileInputFormat.SPLIT_MINSIZE, 1), minSplitSize);
    /*
    关键代码
    totalSize --> 文件中的字节数
    goalSize = totalSize / (numSplits == 0 ? 1 : numSplits) // 每个分区占多少个字节
    goalSize = 字节数/ 分区数 
    实际分区个数 = totalSize / goalSize --> 余数/goalSize > 0.1 商+1(即为实际分区数)
    
    假设字节数为 7 默认分区数为 2:
    goalSize = 7 / 2 -->  3byte
    再根据goalSize计算实际分区数:
    实际分区个数 = 7 / 3  --> 2 余数为 1 ; 1/3 = 0.33 
    所以实际分区数为: 2 + 1 = 3
    
    */
    
    
  • 总结

    文件创建rdd 分区数和hadoop划分数据是一样的

    首先根据 默认分区或者指定的分区数计算每个分区的字节量

    公式: goalSize = totalSize / (numSplits == 0 ? 1 : numSplits)

    描述: 每个分区的字节量 = 总字节数量/ 默认或者指定分区数

    根据每个分区的字节量计算实际的分区数

    实际的分区数 = totalSize / goalSize 如果余数/goalSize 大于0.1 分区数加1

2.1、从集合中创建rdd的分区个数

2.2、从集合中创建rdd的分区数据如何划分

2.3、从外部存储(文件)创建rdd的个数

2.4、从外部存储(文件)创建rdd的数据如何划分

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一年又半

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值