RDD数据集

1. 创建RDD数据集

1. 从现有的Scala集合创建RDD数据集

  1. parallelize(Seq, numSlices):
  • 定义:
    Seq:Array或者List
    numSlices:代表创建的RDD的分区数,如果没传递,有一个默认值,默认分区就是spark.default.parallelism;如果master是local[n],那么这个值就是n,如果yarn和standalone上运行的话,spark.default.parallelism=yarn/standalone的核数
def parallelizeOpt(sc: SparkContext): Unit = {
  println("-------------parallelize开始-------------")
  var rdd = sc.parallelize(Array(1,2,3,4,5,6))
  rdd.foreach(println(_)) // 5 4 2 1 3 6
  println(rdd.getNumPartitions) // 5
  println("-------------parallelize结束-------------")
}
  1. makeRDD也是从集合中创建RDD数据集
    makeRDD(Seq, numSlices) -- 底层是parallelize实现的
def makeRDDOpt(sc: SparkContext) = {
  println("-------------makeRDD开始-------------")
  val rdd1: RDD[Int] = sc.makeRDD(List(1, 2, 3, 4, 5, 6))
  rdd1.foreach(println(_)) // 2 1 4 3 5 6
  println(rdd1.getNumPartitions) // 5
  println("-------------makeRDD结束-------------")
}
  1. makeRDD(Seq( ( T, Seq(String) ) ) ) -- 这种方式可以指定分区数据在那个节点上
def makeRDDAsSeq(sc: SparkContext) = {
  println("-------------makeRDDAsSeq开始-------------")
  val rdd2: RDD[Int] = sc.makeRDD(List((1, List("node1")), (2, List("node1"))))
  rdd2.foreach(println(_)) // 2 1
  println(rdd2.getNumPartitions) // 2
  println("-------------makeRDDAsSeq结束-------------")
}
  1. 分区的设定
Spark中创建RDD有三种方式
1、从现有的Scala集合(Seq集合体系)中创建
(1)parallelize(Seq[T],numSlices)
① Seq[T]: RDD数据集中的数据
② numSlices: RDD的分区数,
(1)分区数指定,指定了分区数那么RDD分区就是指定的分区数据
(2)分区数不用指定,默认值会使用一个函数defaultParallelism计算分区数
    函数计算默认值的规则为scheduler.conf.getInt("spark.default.parallelism", totalCores)
    规则如下:从SparkConf配置文件中获取spark.default.parallelism参数值,如果这个参数没有设置,那么会使用totalCores当作参数的值
    totalCores和环境运行有关
(2)makeRDD(Seq[T],numSlices)---第一种创建方式 底层实现和parallelize一摸一样
   创建的RDD的分区数据规则和parallelize规则一致
(3)makeRDD(Seq[(T,Seq[String])])----第二种makeRDD的创建方式----不常用
   分区数和RDD的数据条数有关,有几条数据就有几个分区

2. 从外部文件系统创建RDD数据集(HDFS)

  • 定义:
    RDD的创建也可以从外部存储创建RDD数据集
    textFile(文件路径,minPartitions)
object TextFileCreateRDD {
  def main(args: Array[String]): Unit = {
    val sparkConf:SparkConf = new SparkConf().setAppName("textFile").setMaster("local[3]")
    val sc:SparkContext = new SparkContext(sparkConf)

    val line: RDD[String] = sc.textFile("hdfs://node1:9000/wc.txt")
    line.foreach(println(_))
    println("分区数为"+line.getNumPartitions) // 5
    sc.stop()
  }
}
  • 分区:
1. 计算minParttions
}
(1)没有传递minPartitions,minPartitions会有一个默认值math.min(defaultParallelism, 2)
defaultParallelism:根据创建rdd的方式,觉得默认值(如:parallelsim,spark.default.parallelism参数值,如果这个参数没有设置,那么会使用totalCores当作参数的值)
(2)传递minPartitions  底层会根据minPartitions计算一个分区值
如果传递的minPartitions值是1,每一个文件是一个分区
如果传递的minPartitions值大于等于2,规则如下:
一.先将数据源的文件大小累加得到字节数,总字节数/传递进来的minPartitions=临时的Size
二.从tempsize和blocksize(说明:如果不在hdfs上blocksize改为32B)取一个最小值(切片),取出来的最小值为splitSize切片的大小
三.每个文件单独切片,文件大小/splitsize,如果大于splitsize的1.1倍,每一个切片就是一个分区。
(源码查看:textFile---->hadoopFile---->HadoopRDD---->getPartitions函数(获取分区数)---->allInputSplits(分区数))
案例如下:
文件1:a.txt 大小40B
文件2:b.txt 大小38B
设置分区为9,blocksize为128B
一.总字节数为40+38=78B,临时大小tempsize为78B/9 = 8B(取整)
二.min(tempsize,blocksize) = 8B,splitSize切片大小为 8B
三.对文件一切片:40B / 8.8B = 4.多 = 5个分区,对文件二切片:38B / 8.8B = 4.多 = 5个分区 所以一共是10个分区
(3)如果传递进来的minPartitions为0或者1,那么数据源有几个文件就有几个分区

3. 从另外一个RDD使用转换算子创建RDD数据集

2. 处理的核数

local 在本地使用1个cpu内核运行
local[n] 在本地使用n个cpu内核运行
local[*] 在本地使用本地所有的内核数运行

3. 键值对RDD初体验

  • scala版本的:
object KVRdd {
  def main(args: Array[String]): Unit = {
    val sparkConf:SparkConf = new SparkConf().setAppName("textFile").setMaster("local[3]")
    val sc:SparkContext = new SparkContext(sparkConf)
    val pairRDD: RDD[(String, Int)] = sc.makeRDD(List(
      ("zs", 1), ("ls", 2), ("ww", 3)
    ))
    pairRDD.foreach(println(_))
    sc.stop()
  }
}
  • java版本的:
public class KVRDD {
    public static void main(String[] args) {
        SparkConf conf = new SparkConf().setAppName("wc").setMaster("local[2]");
        JavaSparkContext jsc = new JavaSparkContext(conf);
        List<Tuple2<String, Integer>> list = new ArrayList<Tuple2<String, Integer>>();
        list.add(new Tuple2<String, Integer>("ww", 1));
        list.add(new Tuple2<String, Integer>("zs", 2));
        list.add(new Tuple2<String, Integer>("aa", 3));
        list.add(new Tuple2<String, Integer>("bb", 4));
        list.add(new Tuple2<String, Integer>("cc", 5));
        list.add(new Tuple2<String, Integer>("dd", 6));

//      有问题会报错  JavaPairRDD<String, Integer> parallelize = jsc.parallelizePairs(list);
        JavaRDD<Tuple2<String, Integer>> parallelize = jsc.parallelize(list);
        System.out.println(parallelize.getNumPartitions());
        parallelize.foreach(new VoidFunction<Tuple2<String, Integer>>() {
            public void call(Tuple2<String, Integer> stringIntegerTuple2) throws Exception {
                System.out.println(stringIntegerTuple2);
            }
        });
        jsc.stop();
    }
}
posted @ 2022-08-25 18:40  jsqup  阅读(101)  评论(0编辑  收藏  举报