1. 创建RDD数据集
1. 从现有的Scala集合创建RDD数据集
- 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(_)) |
| println(rdd.getNumPartitions) |
| println("-------------parallelize结束-------------") |
| } |
- 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结束-------------") |
| } |
- 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结束-------------") |
| } |
- 分区的设定
| 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初体验
| 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() |
| } |
| } |
| 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)); |
| |
| |
| 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(); |
| } |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?