本节课课堂总结:

利用IDEA开发Spark-SQL:

1.创建子模块Spark-SQL,并添加依赖

<dependency>

<groupId>org.apache.spark</groupId>

<artifactId>spark-sql_2.12</artifactId>

<version>3.0.0</version>

</dependency>

2.创建Spark-SQL的测试代码:

case class User(id:Int,name:String,age:Int)

object SparkSQLDemo {

def main(args: ArrayString): Unit = {

//创建上下文环境配置对象

val sparkConf = new SparkConf().setMaster("local\*").setAppName("SQLDemo")

//创建SparkSession对象

val spark :SparkSession = SparkSession.builder().config(sparkConf).getOrCreate()

import spark.implicits._

//读取json文件

val df : DataFrame = spark.read.json("Spark-SQL/input/user.json")

df.show()

//SQL风格语法

df.createOrReplaceTempView("user")

spark.sql("select * from user").show

spark.sql("select avg(age) from user").show

//DSL风格语法

df.select("username","age").show()

//RDD=>DataFrame=>DataSet

//RDD

val rdd1 :RDD(Int,String,Int) = spark.sparkContext.makeRDD(

List((1,"zhangsan",30),(2,"lisi",40))

)

//DataFrame

val df1 :DataFrame = rdd1.toDF("id","name","age")

df1.show()

//DataSet

val ds1 :DatasetUser = df1.asUser

ds1.show()

//DataSet=>DataFrame=>RDD

val df2 =ds1.toDF()

df2.show()

val rdd2 :RDDRow = df2.rdd

rdd2.foreach(a=>println(a.getString(1)))

rdd1.map{

case (id,name,age)=>User(id,name,age)

}.toDS().show()

val rdd3 = ds1.rdd

rdd3.foreach(a=>println(a.age))

rdd3.foreach(a=>println(a.id))

rdd3.foreach(a=>println(a.name))

spark.stop()

}

}

自定义函数:

val sparkConf = new SparkConf().setMaster("local\*").setAppName("SQLDemo")

//创建SparkSession对象

val spark :SparkSession = SparkSession.builder().config(sparkConf).getOrCreate()

import spark.implicits._

//读取json文件

val df : DataFrame = spark.read.json("Spark-SQL/input/user.json")

spark.udf.register("addName",(x:String)=>"Name:"+x)

df.createOrReplaceTempView("people")

spark.sql("select addName(username),age from people").show()

spark.stop()

UDAF(自定义聚合函数)

强类型的 Dataset 和弱类型的 DataFrame 都提供了相关的聚合函数, 如 count(),

countDistinct(),avg(),max(),min()。除此之外,用户可以设定自己的自定义聚合函数。Spark3.0之前我们使用的是UserDefinedAggregateFunction作为自定义聚合函数,从 Spark3.0 版本后可以统一采用强类型聚合函数 Aggregator

实验需求:计算平均工资

实现方式一:RDD

val sparkconf: SparkConf = new SparkConf().setAppName("app").setMaster("local\*")

val sc: SparkContext = new SparkContext(conf)

val resRDD: (Int, Int) = sc.makeRDD(List(("zhangsan", 20), ("lisi", 30), ("wangwu",40))).map {

case (name, salary) => {

(salary, 1)

}

}.reduce {

(t1, t2) => {

(t1._1 + t2._1, t1._2 + t2._2)

}

}

println(resRDD._1/resRDD._2)

// 关闭连接

sc.stop()

实现方式二:弱类型UDAF

class MyAverageUDAF extends UserDefinedAggregateFunction{

def inputSchema: StructType =

StructType(Array(StructField("salary",IntegerType)))

// 聚合函数缓冲区中值的数据类型(salary,count)

def bufferSchema: StructType = {

StructType(Array(StructField("sum",LongType),StructField("count",LongType)))

}

// 函数返回值的数据类型

def dataType: DataType = DoubleType

// 稳定性:对于相同的输入是否一直返回相同的输出。

def deterministic: Boolean = true

// 函数缓冲区初始化

def initialize(buffer: MutableAggregationBuffer): Unit = {

// 存薪资的总和

buffer(0) = 0L

// 存薪资的个数

buffer(1) = 0L

}

// 更新缓冲区中的数据

def update(buffer: MutableAggregationBuffer,input: Row): Unit = {

if (!input.isNullAt(0)) {

buffer(0) = buffer.getLong(0) + input.getInt(0)

buffer(1) = buffer.getLong(1) + 1

}

}

// 合并缓冲区

def merge(buffer1: MutableAggregationBuffer,buffer2: Row): Unit = {

buffer1(0) = buffer1.getLong(0) + buffer2.getLong(0)

buffer1(1) = buffer1.getLong(1) + buffer2.getLong(1)

}

// 计算最终结果

def evaluate(buffer: Row): Double = buffer.getLong(0).toDouble /

buffer.getLong(1)

}

val sparkconf: SparkConf = new SparkConf().setAppName("app").setMaster("local\*")

val spark:SparkSession = SparkSession.builder().config(conf).getOrCreate()

import spark.implicits._

val res :RDD(String,Int)= spark.sparkContext.makeRDD(List(("zhangsan", 20), ("lisi", 30), ("wangwu",40)))

val df :DataFrame = res.toDF("name","salary")

df.createOrReplaceTempView("user")

var myAverage = new MyAverageUDAF

//在 spark 中注册聚合函数

spark.udf.register("avgSalary",myAverage)

spark.sql("select avgSalary(salary) from user").show()

// 关闭连接

spark.stop()

实现方式三:强类型UDAF

case class Buff(var sum:Long,var cnt:Long)

class MyAverageUDAF extends AggregatorLong,Buff,Double{

override def zero: Buff = Buff(0,0)

override def reduce(b: Buff, a: Long): Buff = {

b.sum += a

b.cnt += 1

b

}

override def merge(b1: Buff, b2: Buff): Buff = {

b1.sum += b2.sum

b1.cnt += b2.cnt

b1

}

override def finish(reduction: Buff): Double = {

reduction.sum.toDouble/reduction.cnt

}

override def bufferEncoder: EncoderBuff = Encoders.product

override def outputEncoder: EncoderDouble = Encoders.scalaDouble

}

val sparkconf: SparkConf = new SparkConf().setAppName("app").setMaster("local\*")

val spark:SparkSession = SparkSession.builder().config(conf).getOrCreate()

import spark.implicits._

val res :RDD(String,Int)= spark.sparkContext.makeRDD(List(("zhangsan", 20), ("lisi", 30), ("wangwu",40)))

val df :DataFrame = res.toDF("name","salary")

df.createOrReplaceTempView("user")

var myAverage = new MyAverageUDAF

//在 spark 中注册聚合函数

spark.udf.register("avgSalary",functions.udaf(myAverage))

spark.sql("select avgSalary(salary) from user").show()

// 关闭连接

spark.stop()

相关推荐
中屹指纹浏览器几秒前
2026住宅代理IP纯度检测、链路溯源与指纹浏览器适配调优方案
经验分享·笔记
易知微EasyV数据可视化1 小时前
当AI开始理解物理与场景,数字孪生如何回归其价值本身?
人工智能·经验分享·数字孪生
xuhaoyu_cpp_java9 小时前
项目学习(三)分页查询
java·经验分享·笔记·学习
卡梅德生物科技小能手17 小时前
卡梅德生物科普MCAM(黑色素瘤细胞黏附分子)
人工智能·经验分享·深度学习
huangdong_17 小时前
京东商品图片与视频采集技术深度解析:m3u8视频合并、SKU图提取
经验分享·音视频
BomanGe119 小时前
NSK高刚性精密滚珠丝杠PFT4006详析
经验分享·规格说明书
xuhaoyu_cpp_java19 小时前
项目学习(三)代码生成器
java·经验分享·笔记·学习
智者知已应修善业20 小时前
【51单片机初始化D5-D8亮,每按键按下D1到D4全亮,再按下恢复,如此循环】2024-3-26
c++·经验分享·笔记·算法·51单片机
高校网站建设群系统EduCMS21 小时前
网站群国产化改造升级服务公司,深圳信科网络科技
经验分享