RDD数据集
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(_)) // 5 4 2 1 3 6
println(rdd.getNumPartitions) // 5
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初体验
- 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();
}
}
本文来自博客园,作者:jsqup,转载请注明原文链接:https://www.cnblogs.com/jsqup/p/16621464.html