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等大數據框架。
微信公衆號:精英數據人
● 掃碼關注我們
大數據算法
大數據框架
工程開發專項技能
人工智能前沿探討