Spark RDD 分区数计算详解

基础知识

spark.default.parallelism:(默认的并发数)= 2

当配置文件spark-default.conf中没有显示的配置,则按照如下规则取值:

  • 1、本地模式(不会启动executor,由SparkSubmit进程生成指定数量的线程数来并发):

        spark-shell       spark.default.parallelism = 1

        spark-shell --master local[N] spark.default.parallelism = N (使用N个核)

        spark-shell --master local       spark.default.parallelism = 1

 

  • 2、伪集群模式(x为本机上启动的executor数,y为每个executor使用的core数,z为每个 executor使用的内存)

        spark-shell --master local-cluster[x,y,z] spark.default.parallelism = x * y

 

  • 3、其他模式(这里主要指yarn模式,当然standalone也是如此)

        Others: total number of cores on all executor nodes or 2, whichever is larger

        spark.default.parallelism =  max(所有executor使用的core总数, 2)

经过上面的规则,就能确定了spark.default.parallelism的默认值(前提是配置文件spark-default.conf中没有显示的配置,如果配置了,则spark.default.parallelism = 配置的值)

还有一个配置比较重要,spark.files.maxPartitionBytes = 128 M(默认)
The maximum number of bytes to pack into a single partition when reading files.
代表着rdd的一个分区能存放数据的最大字节数,如果一个400m的文件,只分了两个区,则在action时会发生错误。

当一个spark应用程序执行时,生成spark.context,同时会生成两个参数,由上面得到的spark.default.parallelism推导出这两个参数的值

    sc.defaultParallelism     = spark.default.parallelism

    sc.defaultMinPartitions = min(spark.default.parallelism,2)

当sc.defaultParallelism和sc.defaultMinPartitions最终确认后,就可以推算rdd的分区数了。


产生rdd的几种方式:

 

  • 1、通过scala 集合方式parallelize生成rdd

          如, val rdd = sc.parallelize(1 to 10)

         这种方式下,如果在parallelize操作时没有指定分区数,则

         rdd的分区数 = sc.defaultParallelism

  • 2、通过textFile方式生成的rdd

         如, val rdd = sc.textFile(“path/file”)

         有两种情况:

         a、从本地文件file:///生成的rdd,操作时如果没有指定分区数,则默认分区数规则为:

        rdd的分区数 = max(本地file的分片数, sc.defaultMinPartitions)

          b、从hdfs分布式文件系统hdfs://生成的rdd,操作时如果没有指定分区数,则默认分区数规则为:

        rdd的分区数 = max(hdfs文件的block数目, sc.defaultMinPartitions)

  • 3、从HBase的数据表转换为RDD,则该RDD的分区数为该Table的region数。

    String tableName ="pic_test2";
    conf.set(TableInputFormat.INPUT_TABLE,tableName);
    conf.set(TableInputFormat.SCAN,convertScanToString(scan));
    JavaPairRDD hBaseRDD = sc.newAPIHadoopRDD(conf,TableInputFormat.class,ImmutableBytesWritable.class,Result.class);
    Hbase Table:pic_test2的region为10,则hBaseRDD的分区数也为10。

  • 4、通过获取json(或者parquet等等)文件转换为DataFrame,则该DataFrame的分区数和该文件在文件系统中存放的Block数量对应。

    Dataset<Row> df = spark.read().json("examples/src/main/resources/people.json");
    people.json大小为300M,在HDFS中占用了2个blocks,则该DataFrame df分区数为2。

  • 5、Spark Streaming获取Kafka消息对应的分区数

     a、基于Receiver接收数据

    在Receiver的方式中,Spark中的partition和kafka中的partition并不是相关的,所以如果我们加大每个topic的partition数量,

    仅仅是增加线程来处理由单一Receiver消费的主题。但是这并没有增加Spark在处理数据上的并行度。

     b、基于direct直连方式读取kafka数据

    Spark会创建跟Kafka partition一样多的RDD partition,并且会并行从Kafka中读取数据。

    所以在Kafka partition和RDD partition之间,有一个一对一的映射关系。
 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: SparkRDD(Resilient Distributed Datasets)是一种分布式的据结构,它可以被分割成多个分区,每个分区可以在不同的节点上进行计算RDD提供了一系列的转换和操作函,可以对RDD进行各种操作。 RDD转换函包括map、filter、flatMap、union、distinct、groupByKey、reduceByKey、sortByKey等。这些函可以对RDD进行转换操作,生成新的RDDRDD操作函包括count、collect、reduce、take、foreach等。这些函可以对RDD进行操作,返回结果或者将结果输出到外部系统。 在使用RDD时,需要注意一些问题,如RDD的惰性计算RDD的持久化、RDD分区等。同时,还需要根据实际情况选择合适的RDD转换和操作函,以达到最优的计算效果。 总之,SparkRDD转换和操作函是非常重要的,掌握它们可以帮助我们更好地使用Spark进行分布式计算。 ### 回答2: Spark是一个基于内存计算的分布式计算框架,可以实现大规模据集的快速处理。在SparkRDD(弹性分布式据集)是据处理的核心概念,它是一种可以分区、并行计算和容错的不可变据结构。而Spark的函式编程模型则将RDD的转换与操作都看做是函的调用,从而简洁明了,易于理解和操作。 在Spark,解决一个具体问题通常涉及一系列RDD的转换和操作。RDD的转换包括对原有RDD进行过滤、映射、聚合等处理,得到新的RDD;操作则是对新的RDD进行输出、保存、统计、排序等操作。以下介绍几种常见的RDD转换和操作函。 1. map函 map函是一种转换函,它可以将一个RDD每个元素通过一个用户定义的函映射到另一个RDD,并得到新的RDD。例如,将一个整型RDD的每个元素都乘以2后得到一个新的整型RDD: ``` val rdd1 = sc.parallelize(Array(1, 2, 3, 4)) val rdd2 = rdd1.map(x => x*2) ``` 2. filter函 filter函也是一种转换函,它可以根据用户定义的条件过滤一个RDD的元素,并得到一个新的RDD。例如,将一个字符串RDD长度大于5的元素过滤出来得到一个新的字符串RDD: ``` val rdd1 = sc.parallelize(Array("hello", "world", "spark", "rdd")) val rdd2 = rdd1.filter(x => x.length > 5) ``` 3. reduce函 reduce函是一种操作函,它可以将一个RDD的元素按照用户定义的函进行聚合并得到一个结果。例如,将一个整型RDD的所有元素相加得到一个整结果: ``` val rdd1 = sc.parallelize(Array(1, 2, 3, 4)) val result = rdd1.reduce((x, y) => x + y) ``` 4. collect函 collect函也是一种操作函,它可以将一个RDD的所有元素收集起来并输出到Driver端。然而,使用collect函需要注意RDD的大小,如果RDD很大,就可能会出现内存溢出的情况。例如,将一个整型RDD的所有元素收集起来并输出到屏幕: ``` val rdd1 = sc.parallelize(Array(1, 2, 3, 4)) val result = rdd1.collect() result.foreach(println) ``` 5. saveAsTextFile函 saveAsTextFile函也是一种操作函,它可以将一个RDD的所有元素保存到指定的文本文件。例如,将一个字符串RDD的所有元素保存到hdfs的一个文本文件: ``` val rdd1 = sc.parallelize(Array("hello", "world", "spark", "rdd")) rdd1.saveAsTextFile("hdfs://localhost:8020/user/abc/output") ``` 总之,SparkRDD转换和操作函具有弹性、高效、简单等特点,能够满足各种大规模据处理需求。需要特别注意的是,Spark的函式编程模型是基于JVM的,因此要充分利用内存和CPU资源,需要对集群配置和调优进行一定的优化和测试。 ### 回答3: SparkRDD(Resilient Distributed Datasets)是分布式的弹性据集,它可以在大规模集群上并行化地计算,并且提供了一系列的转换和操作函。其Spark提供的Spark简单易用,具有高效的据处理能力,可以帮助开发者快速开发分布式应用程序。 RDD转换函是将一个RDD转换成另一个RDD的函,转换后的RDD通常包含了据处理、筛选和过滤后的新据集,可以用来接着进行后续的计算。 例如,map函可以将RDD的每个元素应用一个函,然后返回一个新的转换过的RDD: ``` val originalData = sc.parallelize(List(1, 2, 3, 4, 5)) val mappedData = originalData.map(x => x * 2) ``` 这里,map函将原始的每个元素都乘上了2,返回了一个新的RDD。 除了map函, 还有flatMap、filter、groupBy等常用的转换函,都可以帮助我们对RDD做出各种各样的据处理和转换。 RDD操作函则是对RDD进行真正的计算操作,例如reduce、count、collect等函,这些函会触发Spark的分布式计算引擎执行真正的计算任务。 比如,reduce函可以将RDD的所有元素进行聚合,返回一个单一的结果: ``` val originalData = sc.parallelize(List(1, 2, 3, 4, 5)) val reducedData = originalData.reduce(_ + _) ``` 这里,reduce函将原始的所有元素进行相加操作,返回了一个整类型的结果。 Spark提供的操作函非常丰富,从基本的聚合、排序、统计操作,到高级的机器学习和图形处理等操作,开发者可以根据不同的业务需求灵活选择使用。 总之,SparkRDD转换和操作函是分布式据处理的核心之一,通过这些函,开发者能够方便地对海量据进行分布式的计算和处理。同时,Spark也提供了丰富的API和工具,便于开发者进行高效的Spark应用程序开发。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值