1、RDD特性
RDD概念:
RDD为Spark核心抽象,其全名为弹性分布式数据集。看到此名字,千万别认为它只是一个数据集,存放一些计算元数据的逻辑抽象。
RDD的五个特征:
1. 每个RDD都由若干个Partition组成
2. 函数作用在RDD上,这个特点在开发时可以直观感受
3. RDD之间存在依赖关系,这种依赖关系形成“血统图”
4. 携带分区器的RDD决定RDD的分区数量
5. 计算最佳位置的选择(数据本地化)
RDD的弹性体现:
1. RDD数据存储自动进行内存和磁盘之间的切换
2. Lineage的容错机制
3. Task任务失败进行特定次数的重试(默认为4次)
4. Stage失败进行特定次数的重试(默认4次)
5. Checkpoint和persist可主动也可被动触发
6. 数据分片的高度弹性
7、资源调度和Driver任务调度的拆分
Transformation算子分为两类,分类依据为是否需要进行Shuffle操作,本文将用Java和Scala两种语言进行相关算子实战讲述。创建算子之前首先要进行相关抽象的创建,Spark的Sparkcontext相当Spark的引擎,在Java版本下使用JavaSparkContext,在scala版本中使用SparkContext。其创建了DAGscheduler、TaskScheduler、SchedulerBackend以及向Master(ResourceManager)提交Application。对于Java版本本公众号主要使用Java8或更高版本进行编程,为了面向未来技术需求和接轨名企。
创建RDD的方法:
创建方法有三种:textFile、parallelize、makeRDD
textFile底层调用Hadoop的文件读入模块,textFile读入第一个RDD为HadoopRDD并将其隐式转换为MapPartitionRDD。parallelize主要是应用于测试,其并行度默认为处理器的线程数,比如四核那么其并行度为8。makeRDD底层调用parallelize。
2、算子概述
操作的算子:(java版本)
涉及的算子包括:
maptopair
maptopairpartitions
mappartitonwithindex
flatmap
filter
values
keys
makevalues等
尤其是mappartitions、mappartitonwithindex开发使用场景最多
涉及Shuffle的算子包括:
reduceBykey
sortBykey
combineBykey
aggregateBykey
foldBykey
groupBykey
join
leftOutjoin
rightOutjoin
fullOutjoin
substract
repartition
intersection
cogroup
distinct
尽量使用combineBykey、aggregateBykey、reduceBykey,少用groupBykey、cogroup
shuffle操作的算子:(scala版本)
不涉及Shuffle的算子包括:
map
maprpartitions
mappartitonwithindex
flatmap
filter
values
keys
makevalues等
尤其是mappartitions、mappartitonwithindex开发使用场景最多
涉及Shuffle的算子包括:
reduceBykey
sortBykey
combineBykey
aggregateBykey
foldBykey
groupBykey
join
leftOutjoin
rightOutjoin
fullOutjoin
substract
repartition
intersection
cogroup
distinct
尽量使用combineBykey、aggregateBykey、reduceBykey,少用groupBykey、cogroup
实例:
算子详解:
Map:实现一个映射操作。
Maprpartitions:在一个分区上使用映射操作,这个算子实际开发使用,提高吞吐量,消耗低集群资源。
Mappartitonwithindex:该操作可以拿到集群的数据以及分区号,这样便于很多相关操作,针对特殊数据的特殊处理这个算子性能尤为突出。
Flatmap:打平集合中的数据,重新组建集合。
Filter:通过某个条件过滤集合。
Values:返回kv对的value集合。
Keys:返回kv对的key集合。
Makevalues:针对集合value进行进一步操作。
reduceBykey:该操作为聚合操作,其首先局部聚合,然后全局聚合,性能高。
sortBykey:按照key进行排序。
combineBykey:该算子需传入三个参数,第一个value参数,局部操作函数,全局操作函数。
aggregateBykey:该算子输入两个参数,局部操作函数,全局操作函数。
foldBykey:该算子为具有初始值的reduceBykey。
groupBykey:先分组后聚合,此算子性能相对较低,作用在一个RDD上。
reduceBykey、combineBykey、aggregateBykey、foldBykey四个算子底层都是采用combineBykeyClassTag
类SQL的连接操作:
Join
leftOutjoin
rightOutjoin
fullOutjoin
差集与交集:
substract
Intersection
Cogroup:分组聚合,这个是作用在多个RDD上,最多为4个
Distinct:去重,底层采用reduceBykey和map算子
3、实战
实战(scala版本):
object demo{
def main(args: Array[String]): Unit = {
// 设置系统参数
val conf: SparkConf = new SparkConf().setAppName(this.getClass. getSimpleName).setMaster("local[*]")
// 创建sparkcontext
val context = new SparkContext(conf)
//创建RDD
val lines: RDD[String] = context.textFile(args(0))
// 根据打平
val words = lines.flatMap(_.split(" "))
//转为KV
val wordsAndOne = words.mapPartitions(it=>it.map((_,1)))
// 聚合操作
val reduced = wordsAndOne.reduceByKey(_+_)
// 排序
val sorted = reduced.sortBy(_._2,false)
// 保存到特定位置
sorted.saveAsTextFile(args(1))
// 停止一切
context.stop()
}
}
实战(Java版本):
public class Demo{
public static void main(String[] args) {
SparkConf conf = new SparkConf().setAppName("Demo"). setMaster("local[*]");
JavaSparkContext javaSparkContext = new JavaSparkContext(conf);
JavaRDD<String> lines = javaSparkContext.textFile(args[0]);
JavaRDD<String> words = lines.flatMap(line -> Arrays.asList(line.split(" ")).iterator());
JavaPairRDD<String, Integer> pairRDD = words.mapToPair(word -> Tuple2.apply(word, 1));
JavaPairRDD<String, Integer> reduce = pairRDD.reduceByKey((a,b)-> a+b);
JavaPairRDD<Integer, String> swaped = reduce.mapToPair(tp -> tp.swap());
JavaPairRDD<Integer, String> sorted = swaped.sortByKey(false);
JavaPairRDD<String, Integer> result = sorted.mapToPair(tp -> tp.swap());
result.saveAsTextFile(args[1]);
javaSparkContext.stop();
}
}
作者简介
本人Doug,从事数据处理5年,大数据处理3年。目前主要从事大数据算法和框架研究,精通Java、Scala和Python编程,熟悉并发编程和工程开发过程,精通Flume、Sqoop、Hadoop、Hive、HBase、Spark、Flink等大数据框架。
微信公众号:精英数据人
● 扫码关注我们
大数据算法
大数据框架
工程开发专项技能
人工智能前沿探讨