RDD 核心术语
名称 | 含义 |
Application | Spark的应用程序,包含一个Driver program和若干个Executor |
Driver Program | 运行Application的main()函数并创建SparkContext |
SaprkContext | Spark应用程序的入口,负责调度work的原酸资源,协调WorkerNode上的Executor |
Executor | 是Application运行在Work Node 上的一个进程,该进程负责运行Task,并且负责将数据存在内存或者磁盘上,每个Application都会申请各自的Executor处理任务 |
Cluster Manger | 在集群上获取资源的外部服务(eg: Standalone、Mesos,Yarn) |
Work Node | 在集群中任何可以运行Application代码的节点,运行一个或者多个Executor进程 |
Task | 运行在Executor上的工作单元 |
Job | SparkContext提交具体的Action一系列操作 |
Stage | 每个Job会被拆分为很多组任务(Task),每组任务被称为Stage,也成为 TaskSet |
RDD | Spark核心模块和类 |
DAG Scheduler | 根据Job构建基于Stage的DAG,并提交Stage给TaskScheduler |
Task Scherduler | 将Taskset提交给Worker node,集群运行并返回结果 |
Transformations/Actions | Spark API的两种类型之一,Transformations返回值还是一个RDD,Actions返回值不是一个RDD,而是一个Scala集合,所有的Transformations都是采用的Lazy策略,如果只是将Transformation提交时不会执行计算的,计算只会在Action提交时才会被触发。 |
RDD 分区
RDD 对象实质上是一个元数据结构,存储着Block、Node等映射关系,以及其他元数据信息。一个RDD就是一组分区(Partition),RDD的每个分区Partition对应一个Block,Block可以存储在内存,当内存不够时可以存储到磁盘上。
RDD 的数据源也可以存储在HDFS上,数据按照HDFS分部策略进行分区,HDFS中的一个Block对应SparkRDD的一个Partition。
RDD 依赖
分为 “宽依赖” (Narrow) 和 “窄依赖” (Wide)
RDD 核心概念
RDD 中可看到Task和Partition一对一对应
计算向数据移动的体现
STAGE DAG
SPARK 调度
SPARK API
Transformations: SparkAPI的两种类型之一,Transformations返回值还是一个RDD
Actions: Actions返回值不是一个RDD,而是一个Scala集合
所有Transformations都是采用Lazy策略,如果只是将Transformation提交是不会执行计算的,计算只会在Action提交时才会被触发
Transformations 算子
算子名称 map(func)
功能:将RDD 中的数据映射成另一个RDD中的元素。输入三行、输出三行。
算子名称 filter(func)
功能:对RDD中的数据进行过滤。
// An highlighted block
package ypl.com
import org.apache.log4j.{Level, Logger}
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
object MapFilter {
def main(args: Array[String]): Unit = {
Logger.getLogger("org").setLevel(Level.ERROR)
val sparkconf: SparkConf = new SparkConf().setAppName("spark api").setMaster("local")
val sparkcontext: SparkContext = new SparkContext(sparkconf)
val data: Array[Int] = Array(1, 2, 3, 4, 5)
val inputRdd: RDD[Int] = sparkcontext.parallelize(data)
inputRdd.map(x=>{
x*2
}).filter(_>5)
.foreach(println(_))
// inputRdd.collect().foreach(println(_))
}
}
#######################结果:#######################
6
8
10
####################################################
算子名称 flatMap(func)
功能:对RDD中的数据进行映射后,并将数据进行打散。输入三行,三列。输出九行。
// An highlighted block
inputRdd2.flatMap(
x=>{
x.map(y=>{
y*2
})
}
).foreach(println(_))
#################### 结果 ###################
2
4
6
8
- FlatMap 与 map 之间的区别
算子名称 mapPartitions(func)
功能:和 map 算子相似。应用场景像是建立数据库连接,面向partition。或者对所在分区集合进行操作。
val data: Array[Int] = Array(1, 2, 3, 4, 5)
val inputRdd: RDD[Int] = sparkContext.parallelize(data)
inputRdd.mapPartitions(x=>{
//database connection
x.map(
// database Insert
y=>{
y * 2
}
)
}).foreach(println(_))
}
算子名称 mapPartitionsWithIndex(func)
功能:和 mapPartitions 并返回数据所在的索引位置。
inputRdd.mapPartitionsWithIndex((idx,iter)=>{
iter.map(x=>{
(idx,x)
})
}).foreach(println(_))
算子名称 sample(withReplacement,fraction,seed)
功能:对RDD进行随机抽样。 第一个参数 true 表示是否拿重复的。
val data: Array[Int] = Array(1, 2, 3, 4, 5,200,600,100,300,700,22,66,33)
val inputRdd: RDD[Int] = sparkContext.parallelize(data,4)
inputRdd.sample(true,0.5).foreach(println(_))
2
3
4
200
100
66
算子名称 union(otherDataset)
功能:对RDD进行拼接。
val data: Array[Int] = Array(1, 2, 3, 4, 5)
val inputRdd: RDD[Int] = sparkcontext.parallelize(data)
val rdd1 = inputRdd.map((_,1))
val rdd2= inputRdd.map(_*2).map((_,1))
// union
val rdd_union = rdd1.union(rdd2)
rdd_union.foreach(println(_))
#################### 结果 ###################
(1,1)
(2,1)
(3,1)
(4,1)
(5,1)
(2,1)
(4,1)
(6,1)
(8,1)
(10,1)
算子名称 intersection(otherDataset)
功能:获取两个RDD 的交集
rdd1.intersection(rdd2).foreach(println(_))
######### intersection #############
(4,1)
(2,1)
算子名称 distinct(numTasks)
功能:返回一个对源 dataset 进行去重的 新dataset
// An highlighted block
var foo = 'bar';
算子名称 groupBy(传入key)
功能:对key进行聚合,value是 k,v
val data = Array(Tuple2(1,2),Tuple2(1,3),Tuple2(1,4),Tuple2(2,2),Tuple2(2,1),Tuple2(3,2),Tuple2(3,5))
val inputRdd = sparkContext.parallelize(data)
inputRdd.groupBy(_._1).foreach(println(_))
############# 按照key分组,value 是 kv #############
(1,CompactBuffer((1,2), (1,3), (1,4)))
(3,CompactBuffer((3,2), (3,5)))
(2,CompactBuffer((2,2), (2,1)))
算子名称 groupByKey([numTasks])
功能:按照key进行分组,有大量的shuffle操作。
val data = Array(Tuple2(1,2),Tuple2(1,3),Tuple2(1,4),Tuple2(2,2),Tuple2(2,1),Tuple2(3,2),Tuple2(3,5))
val inputRdd = sparkContext.parallelize(data)
inputRdd.groupByKey().foreach(println(_))
############# 按照key分组,value 是 v #############
(1,CompactBuffer(2, 3, 4))
(3,CompactBuffer(2, 5))
(2,CompactBuffer(2, 1))
inputRdd.groupByKey().map(x=>{
val key = x._1
var sum = 0
x._2.map(y =>{
sum+= y
})
(key,sum)
}).foreach(println(_))
算子名称 reduceByKey(func,[numTasks])
功能:将value 进行聚合或者相加,相比 groupbykey,会提前进行combiner操作。
// An highlighted block
val data = Array(Tuple2(1,2),Tuple2(1,3),Tuple2(1,4),Tuple2(2,2),Tuple2(2,1),Tuple2(3,2),Tuple2(3,5))
val inputRdd = sparkContext.parallelize(data)
inputRdd.reduceByKey(_+_).foreach(println(_))
(1,9)
(3,7)
(2,3)
二者不一样是按照Map reduce的理解来看,reducebykey有提前 combiner的操作。
算子名称 aggregareByKey([numTasks])
功能:返回一个对源 dataset 进行去重的 新dataset
// An highlighted block
var foo = 'bar';
算子名称 sortByKey([numTasks])
功能:返回一个对源 dataset 进行去重的 新dataset
// An highlighted block
var foo = 'bar';
算子名称 join([numTasks])
功能:返回一个 rdd 按照 map的key 聚合,value进行追加
val data: Array[Int] = Array(1, 2, 3, 4, 5)
val inputRdd: RDD[Int] = sparkcontext.parallelize(data)
val rdd1 = inputRdd.map((_,1))
val rdd2= inputRdd.map(_*2).map((_,1))
########## rdd1 ############
(1,1)
(2,1)
(3,1)
(4,1)
(5,1)
######### rdd2 #############
(2,1)
(4,1)
(6,1)
(8,1)
(10,1)
######### join #############
(4,(1,1))
(2,(1,1))
Process finished with exit code 0
算子名称 cogroup([numTasks])
功能 类似 full join
val data: Array[Int] = Array(1, 2, 3, 4, 5)
val inputRdd: RDD[Int] = sparkcontext.parallelize(data)
val rdd1 = inputRdd.map((_,1))
val rdd2= inputRdd.map(_*2).map((_,1))
rdd1.cogroup(rdd2).foreach(println(_))
######### cogroup #############
(4,(CompactBuffer(1),CompactBuffer(1)))
(1,(CompactBuffer(1),CompactBuffer()))
(6,(CompactBuffer(),CompactBuffer(1)))
(3,(CompactBuffer(1),CompactBuffer()))
(8,(CompactBuffer(),CompactBuffer(1)))
(10,(CompactBuffer(),CompactBuffer(1)))
(5,(CompactBuffer(1),CompactBuffer()))
(2,(CompactBuffer(1),CompactBuffer(1)))
Process finished with exit code 0
算子名称 cartesian([otherDataset])
功能:返回一个笛卡尔积
rdd1.cartesian(rdd2).foreach(println(_))
((1,1),(2,1))
((1,1),(4,1))
((1,1),(6,1))
((1,1),(8,1))
((1,1),(10,1))
((2,1),(2,1))
((2,1),(4,1))
((2,1),(6,1))
((2,1),(8,1))
((2,1),(10,1))
((3,1),(2,1))
((3,1),(4,1))
((3,1),(6,1))
((3,1),(8,1))
((3,1),(10,1))
((4,1),(2,1))
((4,1),(4,1))
((4,1),(6,1))
((4,1),(8,1))
((4,1),(10,1))
((5,1),(2,1))
((5,1),(4,1))
((5,1),(6,1))
((5,1),(8,1))
((5,1),(10,1))
Process finished with exit code 0
算子名称 pipe([command,[envVars]])
功能:传入 linux shell
inputRdd.pipe("head -1 ")
算子名称 coalesce(numPartitions)
功能:指定rdd 有几个分区,并且可以选择是否进行 shuffle操作。
数据分布不均,优化的选择。
inputRdd.coalesce(2,false).mapPartitionsWithIndex((idx,iter)=>{
iter.map(x=>{
(idx,x)
})
}).foreach(println(_))
}
#############输出结果################
(0,2)
(0,3)
(0,4)
(0,5)
(0,200)
(1,600)
(1,100)
(1,300)
(1,700)
(1,22)
(1,66)
(1,33)
Process finished with exit code 0
算子名称 repatition(numPartitions)
功能:对RDD 进行重新分区,底层是 coalesce 算子,默认shuffle
数据分布不均,优化的选择。
inputRdd.repartition(5).mapPartitionsWithIndex((idx,iter)=>{
iter.map(x=>{
(idx,x)
})
})//.foreach(println(_))
ACTIONS 算子
算子名称 reduce(func)
功能:对RDD 进行聚合
// An highlighted block
var foo = 'bar';
算子名称 collect()
功能: 数据会收集到 driver。
val data: Array[Int] = Array(1, 2, 3, 4, 5,200,600,100,300,700,22,66,33)
val inputRdd: RDD[Int] = sparkContext.parallelize(data,4)
inputRdd.collect()
算子名称 count()
功能:返回 dataset 的对象的数量
// An highlighted block
var foo = 'bar';
算子名称 first()
功能:返回 第一个
inputRdd.first(10)
算子名称 take()
功能:返回 前 n 个
inputRdd.take(10)
算子名称 takeSample(withReplacement,num,[seed])
功能:随机返回几个
// An highlighted block
var foo = 'bar';
算子名称 takeOrdered(n,[ordering])
功能:排序过后取值
// An highlighted block
var foo = 'bar';
算子名称 saveAsTextFile(n,[ordering])
功能:存储到文件
// An highlighted block
var foo = 'bar';
算子名称 saveAsSequenceFile(n,[ordering])
功能:存储到序列化文件
// An highlighted block
var foo = 'bar';
算子名称 saveAsObjectFile(n,[ordering])
功能:存储成对象文件
// An highlighted block
var foo = 'bar';
算子名称 countByKey()
功能:按照key进行聚合并统计数量
// An highlighted block
var foo = 'bar';
算子名称 foreach(func)
功能:把每个数据遍历一遍
// An highlighted block
var foo = 'bar';
IO 读取hdfs 文件
Logger.getLogger("org").setLevel(Level.ERROR)
val sparkconf: SparkConf = new SparkConf().setAppName("spark api").setMaster("local")
val sparkContext: SparkContext = new SparkContext(sparkconf)
val inputRDD: RDD[String] = sparkContext.textFile("/Users/michale/Desktop/tmp/Spark-API/src/main/resources/*")
inputRDD.foreach(println(_))
路径可以是文件,也可以是目录。
SPARK 创建
// An highlighted block
val conf = new SparkConf().setAppName(appName).setMaster(master)
new SparkContext(conf)