在学习spark批处理的时候,join是最常规的操作,本文主要是通过使用spark core和spark sql两种方式实现join操作
spark官方推荐spark sql,因为spark sql支持对dataframe(Dataset的特列,DataFrame=Dataset[Row] )进行操作,很多数据分析人员习惯使用python,而python没有dataset,而且sql方式对数据进行批处理方式更为直观。
spark core方式
package com.zero.scala.sparkCore
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
/**
* rdd的join用sparkcontext,如果是sparksql的join那就用sparksession
*
*/
object SparkRddJoinOps {
case class work(
sid:String,
job:String,
kind:String
)
def main(args: Array[String]): Unit = {
//创建sparkcontext
val conf = new SparkConf().setAppName("SparkRddJoin").setMaster("local[4]")
val sc = new SparkContext(conf)
//创建rdd1:包含id和职业,id:1,2,3,4
val work_list = List("1,spark,bigdata",
"2,mapreduce,bigdata",
"3,flink,bigdata",
"4,storm,bigdata")
val workRdd = sc.parallelize(work_list)
println("workRdd:"+ workRdd)
val wordPairRdd:RDD[(String,work)] = workRdd.map(line =>{
val words = line.split(",")
val wk = work(words(0),words(1),words(2))
(words(0),wk)
})
val rdd1 = sc.makeRDD(Array(("1","spark"),("2","mapreduce"),("3","flink"),("4","storm")))
//创建rdd2:包含id和薪水,id:1,2,3,5
val rdd2 = sc.makeRDD(Array(("1","40k"),("2","20k"),("3","45k"),("5","80k")))
//join操作
println("下面开始进行join操作,结果如下:")
println("joinRdd1 结果如下:")
val joinRdd1 = rdd1.join(rdd2).foreach(println)
println("joinRdd2 结果如下:")
val joinRdd2 = wordPairRdd.join(rdd2).foreach(println)
//leftOuterJoin操作
println("下面开始进行leftOuterJoin操作,结果如下:")
println("leftOuterJoinRdd3 结果如下:")
val leftOuterJoinRdd3 = rdd1.leftOuterJoin(rdd2).foreach(println)
println("leftOuterJoinRdd4 结果如下:")
val leftOuterJoinRdd4 = wordPairRdd.leftOuterJoin(rdd2).foreach(println)
sc.stop()
}
}
输出结果如下:
--下面开始进行join操作,结果如下:
--joinRdd1 结果如下:
(2,(mapreduce,20k))
(3,(flink,45k))
(1,(spark,40k))
--joinRdd2 结果如下:
(2,(work(2,mapreduce,bigdata),20k))
(1,(work(1,spark,bigdata),40k))
(3,(work(3,flink,bigdata),45k))
--下面开始进行leftOuterJoin操作,结果如下:
--leftOuterJoinRdd3 结果如下:
(2,(mapreduce,Some(20k)))
(4,(storm,None))
(3,(flink,Some(45k)))
(1,(spark,Some(40k)))
--leftOuterJoinRdd4 结果如下:
(2,(work(2,mapreduce,bigdata),Some(20k)))
(3,(work(3,flink,bigdata),Some(45k)))
(1,(work(1,spark,bigdata),Some(40k)))
(4,(work(4,storm,bigdata),None))
spark sql方式
此处使用spark sql读取hive表进行join操作
package com.zero.scala.sparkSql
import org.apache.spark.sql.{DataFrame, SparkSession}
import scala.collection.mutable.ArrayBuffer
/**
* sparksql 对hive表进行join
* 使用sparksession
*/
object SparkHiveOps {
var sparkSession:SparkSession = _
private def create_sparksession():SparkSession = {
val hiveMetaUris = "thrift://xxx.xxx.xxx.xxx:9083"
SparkSession.builder().master("local[*]")
.appName("createSparkSession")
.enableHiveSupport()
.config("hive.metastore.warehouse.dir","/user/hive/warehouse")
.config("hive.metastore.uris","hiveMetaUris")
.getOrCreate()
}
private def init() :Unit = {
sparkSession = create_sparksession()
sparkSession.sql("use zeroDb")
}
private def destroy_sparkSession(ss:SparkSession) : Unit ={
if(ss != null) ss.close()
}
/**
* join
*/
private def joinOps():DataFrame = {
sparkSession.sql("select a.c1,a.c2,b.c2 from zero_test_a a left join zero_test_b b on a.c1=b.c1 where b.c2='xxx'")
}
def main(args: Array[String]): Unit = {
init()
joinOps().show(5)
destroy_sparkSession(sparkSession)
}
}