package cn.allengao.exercise
import org.apache.spark.{SparkConf, SparkContext}
/**
* class_name:
* package:
* describe: SparkRDD算子練習
* creat_user: Allen Gao
* creat_date: 2018/1/25
* creat_time: 10:04
**/
object SparkRDDTest {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName("SparkRDDTest").setMaster("local")
val sc = new SparkContext(conf)
//通過並行化生成rdd
val rdd1 = sc.parallelize(List(5, 6, 4, 7, 3, 8, 2, 9, 1, 10))
//對rdd1裏面的每一個元素乘以2然後排序,true表示正序排序,false表示倒序排序
val res1 = rdd1.map(_ * 2).sortBy(x => x, true)
//過濾出大於等於10的元素
val res2 = res1.filter(_ >= 10)
val rdd2 = sc.parallelize(Array("a b c", "d e f", "h i j"))
//將rdd2裏面的每一個元素先切分再壓平
val res3 = rdd2.flatMap(_.split(" "))
val rdd3 = sc.parallelize(List(List("a b c", "a b b"), List("e f g", "a f g"), List("h i j", "a a b")))
//將rdd3裏面的每一個元素先切分再壓平
val res4 = rdd3.flatMap(_.flatMap(_.split(" ")))
val rdd4 = sc.parallelize(List(5, 6, 4, 3))
val rdd5 = sc.parallelize(List(1, 2, 3, 4))
//求並集
val res5 = rdd4.union(rdd5)
//求交集
val res6 = rdd4.intersection(rdd5)
//去重
val res7 = rdd4.union(rdd5).distinct()
val rdd6 = sc.parallelize(List(("tom", 1), ("jerry", 3), ("kitty", 2)))
val rdd7 = sc.parallelize(List(("jerry", 2), ("tom", 1), ("shuke", 2)))
//求join
val res8 = rdd6.join(rdd7)
//求左連接和右連接
val res9 = rdd6.leftOuterJoin(rdd7)
val res10 = rdd6.rightOuterJoin(rdd7)
//求並集,這裏注意到不用 “.union” 也可以,非常強大
val res11 = rdd6 union (rdd7)
//按key進行分組
val res12 = res11.groupByKey()
//分別用groupByKey和reduceByKey實現單詞計數,注意groupByKey與reduceByKey的區別
//groupByKey
val res13 = res11.groupByKey().mapValues(_.sum)
/*
groupByKey:groupByKey會對每一個RDD中的value值進行聚合形成一個序列(Iterator),
此操作發生在reduce端,所以勢必會將所有的數據通過網絡進行傳輸,造成不必要的浪費。
同時如果數據量十分大,可能還會造成OutOfMemoryError。
*/
//reduceByValue,先進行局部聚合,再進行全局聚合
val res14 = res11.reduceByKey(_ + _)
/*reduceByKey:reduceByKey會在結果發送至reducer之前會對每個mapper在本地進行merge,
有點類似於在MapReduce中的combiner。這樣做的好處在於,在map端進行一次reduce之後,
數據量會大幅度減小,從而減小傳輸,保證reduce端能夠更快的進行結果計算。
*/
val rdd8 = sc.parallelize(List(("tom", 1), ("tom", 2), ("jerry", 3), ("kitty", 2)))
val rdd9 = sc.parallelize(List(("jerry", 2), ("tom", 1), ("shuke", 2)))
//cogroup 注意cogroup與groupByKey的區別
val res15 = rdd8.cogroup(rdd9)
val rdd10 = sc.parallelize(List(1, 2, 3, 4, 5))
//reduce聚合
val res16 = rdd10.reduce(_ + _)
val rdd11 = sc.parallelize(List(("tom", 1), ("jerry", 3), ("kitty", 2), ("shuke", 1)))
val rdd12 = sc.parallelize(List(("jerry", 2), ("tom", 3), ("shuke", 2), ("kitty", 5)))
val rdd13 = rdd11.union(rdd12)
//按key進行聚合
val res17 = rdd13.reduceByKey(_ + _)
//按value的降序排序
val res18 = rdd13.reduceByKey(_ + _).map(t=>(t._2,t._1)).sortByKey(false).map(t=>(t._2,t._1))
/*
笛卡爾積:
笛卡爾乘積是指在數學中,兩個集合X和Y的笛卡尓積(Cartesian product),又稱直積,
表示爲X×Y,第一個對象是X的成員而第二個對象是Y的所有可能有序對的其中一個成員[3] 。
假設集合A={a, b},集合B={0, 1, 2},則兩個集合的笛卡爾積爲{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}。
*/
val res19 = rdd11.cartesian(rdd12)
//要通過action類型的算子才能顯示出結果,將結果放到可變數組中,就可以看到輸出結果,
// 如果不加toBuffer,則打印出來的是一個引用。
//執行結果:ArrayBuffer(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
// println(res1.collect().toBuffer)
//執行結果:ArrayBuffer(10,12, 14, 16, 18, 20)
// println(res2.collect().toBuffer) //將元素以數組的方式打印出來
//執行結果:ArrayBuffer(a, b, c, d, e, f, h, i, j)
// println(res3.collect().toBuffer)
//執行結果:ArrayBuffer(a, b, c, a, b, b, e, f, g, a, f, g, h, i, j, a, a, b)
// println(res4.collect().toBuffer)
//執行結果:ArrayBuffer(5, 6, 4, 3, 1, 2, 3, 4)
// println(res5.collect().toBuffer)
//執行結果:ArrayBuffer(4, 3)
// println(res6.collect().toBuffer)
//執行結果:ArrayBuffer(4, 6, 2, 1, 3, 5)
// println(res7.collect().toBuffer)
//執行結果:ArrayBuffer((tom,(1,1)), (jerry,(3,2)))
// println(res8.collect().toBuffer)
//執行結果:ArrayBuffer((tom,(1,Some(1))), (jerry,(3,Some(2))), (kitty,(2,None)))
// println(res9.collect().toBuffer)
//執行結果:ArrayBuffer((tom,(Some(1),1)), (jerry,(Some(3),2)), (shuke,(None,2)))
// println(res10.collect().toBuffer)
//執行結果:ArrayBuffer((tom,1), (jerry,3), (kitty,2), (jerry,2), (tom,1), (shuke,2))
// println(res11.collect().toBuffer)
//執行結果:ArrayBuffer((tom,CompactBuffer(1, 1)), (jerry,CompactBuffer(3, 2)), (shuke,CompactBuffer(2)), (kitty,CompactBuffer(2)))
// println(res12.collect().toBuffer)
//執行結果:ArrayBuffer((tom,2), (jerry,5), (shuke,2), (kitty,2))
// println(res13.collect().toBuffer)
//執行結果:ArrayBuffer((tom,2), (jerry,5), (shuke,2), (kitty,2))
// println(res14.collect().toBuffer)
//執行結果:ArrayBuffer((tom,(CompactBuffer(1, 2),CompactBuffer(1))), (jerry,(CompactBuffer(3),CompactBuffer(2))), (shuke,(CompactBuffer(),CompactBuffer(2))), (kitty,(CompactBuffer(2),CompactBuffer())))
// println(res15.collect().toBuffer)
//執行結果:15
//println(res16)
//執行結果:ArrayBuffer((tom,4), (jerry,5), (shuke,3), (kitty,7))
// println(res17.collect().toBuffer)
//執行結果:ArrayBuffer((kitty,7), (jerry,5), (tom,4), (shuke,3))
// println(res18.collect().toBuffer)
/*
執行結果:ArrayBuffer(((tom,1),(jerry,2)), ((tom,1),(tom,3)), ((tom,1),(shuke,2)),
((tom,1),(kitty,5)), ((jerry,3),(jerry,2)), ((jerry,3),(tom,3)), ((jerry,3),(shuke,2)),
((jerry,3),(kitty,5)), ((kitty,2),(jerry,2)), ((kitty,2),(tom,3)), ((kitty,2),(shuke,2)),
((kitty,2),(kitty,5)), ((shuke,1),(jerry,2)), ((shuke,1),(tom,3)), ((shuke,1),(shuke,2)),
((shuke,1),(kitty,5)))
*/
println(res19.collect().toBuffer)
}
}
Spark常用算子練習
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.