Spark之UDAF
一.简介
Spark的自定义udf和udaf是为了提供函数扩展,Spark本身提供了几十上百个算子,在数据分析的各个方面的常用计算方式都有提到,但计算场景千差万别,算子也不会面面俱到,如何在单机或集群上定义函数就是要重点关注的地方。特别是在集群模式中,函数需要使用spark注册才能在各个节点上使用,因此,udf和udaf就显得比较重要了。
二.设置日志级别
Logger.getLogger("org").setLevel(Level.WARN) // 设置日志级别为WARN
三.创建spark入口
val spark = SparkSession.builder().appName("UdfUdaf").master("local[2]").getOrCreate()
val sc = spark.sparkContext
val sqlContext = spark.sqlContext
四.创建测试数据
val userData = Array(
"2015,11,www.baidu.com", "2016,14,www.google.com",
"2017,13,www.apache.com", "2015,21,www.spark.com",
"2016,32,www.hadoop.com", "2017,18,www.solr.com",
"2017,14,www.hive.com"
) val userDataRDD = sc.parallelize(userData) // 转化为RDD
val userDataType = userDataRDD.map(line => {
val Array(age, id, url) = line.split(",")
Row(age, id.toInt, url)
})
val structTypes = StructType(Array(
StructField("age", StringType, true),
StructField("id", IntegerType, true),
StructField("url", StringType, true)
))
// RDD转化为DataFrame
val userDataFrame = sqlContext.createDataFrame(userDataType,structTypes)
// 注冊临时表
userDataFrame.createOrReplaceTempView("udf")
五.自定义udf并测试
def isAdult(age : Int) ={
if(age > 18){
true
}else{
false
}
}
// 注册udf(方式一)
spark.udf.register("isAdult_1", (id : Int) => if(id > 18) true else false) // 匿名函数
// 注册udf(方式二)
spark.udf.register("isAdult_2", isAdult _) // 预先定义好的普通函数
// 验证udf方式一
val result_1 = sqlContext.sql("select * from udf where isAdult_1(udf.id)")
result_1.show(false)
// 验证udf方式二
val result_2 = sqlContext.sql("select * from udf where isAdult_2(udf.id)")
result_2.show(false)
六.执行结果
七.自定义udaf并测试
object AverageUserDefinedAggregateFunction extends UserDefinedAggregateFunction{
//聚合函数输入数据结构
override def inputSchema:StructType = StructType(StructField("input", LongType) :: Nil)
//缓存区数据结构
override def bufferSchema: StructType = StructType(StructField("sum", LongType) :: StructField("count", LongType) :: Nil)
//结果数据结构
override def dataType : DataType = DoubleType
// 是否具有唯一性
override def deterministic : Boolean = true
//初始化
override def initialize(buffer : MutableAggregationBuffer) : Unit = {
buffer(0) = 0L
buffer(1) = 0L
}
//数据处理 : 必写,其它方法可选,使用默认
override def update(buffer: MutableAggregationBuffer, input: Row): Unit = {
if(input.isNullAt(0)) return
buffer(0) = buffer.getLong(0) + input.getLong(0) //求和
buffer(1) = buffer.getLong(1) + 1 //计数
}
//合并
override def merge(bufferLeft: MutableAggregationBuffer, bufferRight: Row): Unit ={
bufferLeft(0) = bufferLeft.getLong(0) + bufferRight.getLong(0)
bufferLeft(1) = bufferLeft.getLong(1) + bufferRight.getLong(1)
}
//计算结果
override def evaluate(buffer: Row): Any = buffer.getLong(0).toDouble / buffer.getLong(1)
}
/**
* 测试udaf
*/
spark.udf.register("average", AverageUserDefinedAggregateFunction)
spark.sql("select count(*) count,average(age) avg_age from udf").show(false)
八.执行结果
Spark之UDAF的更多相关文章
- Spark SQL UDAF示例
UDAF:用户自定义聚合函数 Scala 2.10.7,spark 2.0.0 package UDF_UDAF import java.util import org.apache.spark.Sp ...
- Spark笔记之使用UDAF(User Defined Aggregate Function)
一.UDAF简介 先解释一下什么是UDAF(User Defined Aggregate Function),即用户定义的聚合函数,聚合函数和普通函数的区别是什么呢,普通函数是接受一行输入产生一个输出 ...
- Kafka:ZK+Kafka+Spark Streaming集群环境搭建(十五)Spark编写UDF、UDAF、Agg函数
Spark Sql提供了丰富的内置函数让开发者来使用,但实际开发业务场景可能很复杂,内置函数不能够满足业务需求,因此spark sql提供了可扩展的内置函数. UDF:是普通函数,输入一个或多个参数, ...
- Spark Sql的UDF和UDAF函数
Spark Sql提供了丰富的内置函数供猿友们使用,辣为何还要用户自定义函数呢?实际的业务场景可能很复杂,内置函数hold不住,所以spark sql提供了可扩展的内置函数接口:哥们,你的业务太变态了 ...
- spark编写UDF和UDAF
UDF: 一.编写udf类,在其中定义udf函数 package spark._sql.UDF import org.apache.spark.sql.functions._ /** * AUTHOR ...
- spark自定义函数之——UDAF使用详解及代码示例
UDAF简介 UDAF(User Defined Aggregate Function)即用户定义的聚合函数,聚合函数和普通函数的区别是什么呢,普通函数是接受一行输入产生一个输出,聚合函数是接受一组( ...
- 【转】Spark-Sql版本升级对应的新特性汇总
Spark-Sql版本升级对应的新特性汇总 SparkSQL的前身是Shark.由于Shark自身的不完善,2014年6月1日Reynold Xin宣布:停止对Shark的开发.SparkSQL抛弃原 ...
- 转:Spark User Defined Aggregate Function (UDAF) using Java
Sometimes the aggregate functions provided by Spark are not adequate, so Spark has a provision of ac ...
- Spark SQL 用户自定义函数UDF、用户自定义聚合函数UDAF 教程(Java踩坑教学版)
在Spark中,也支持Hive中的自定义函数.自定义函数大致可以分为三种: UDF(User-Defined-Function),即最基本的自定义函数,类似to_char,to_date等 UDAF( ...
随机推荐
- MySQL社区版升级到Percona Server
出于磁盘空间的考虑,在调研以后把磁盘空间紧张的库的引擎改为tokudb,(在改为tokudb引擎之前是innodb引擎,已经压缩过,但空间还是紧张)关于tokudb的优势各位自行查阅相关资料.要启用t ...
- Ubuntu环境下mysql常见的操作
1 启动mysql服务:Service mysql start 再次启动:service mysql restart 停止mysql服务:service mysql stop 确定mysql是否 ...
- Linux软件包管理之源码包、脚本安装包
目录 1.源码包和RPM包的区别 RPM包和源码包默认安装位置: 由于安装位置不同带来的影响 2.源码包安装 ①.安装准备 ②.安装注意事项 ③.安装源码包 3.源码包卸载 4.脚本安装包 5.总结 ...
- tp3.2多个或者并且语句语法
$map['tid1&cid1'] =array($jmid,'0','_multi'=>true); $map['tid2&cid2'] =array($jmid,'0','_ ...
- 翻译:DECLARE HANDLER语句(已提交到MariaDB官方手册)
本文为mariadb官方手册:DECLARE HANDLER的译文. 原文:https://mariadb.com/kb/en/library/declare-handler/我提交到MariaDB官 ...
- spark高可用集群搭建及运行测试
文中的所有操作都是在之前的文章spark集群的搭建基础上建立的,重复操作已经简写: 之前的配置中使用了master01.slave01.slave02.slave03: 本篇文章还要添加master0 ...
- 小型音乐播放器插件APlayer.js的简单使用例子
本篇博客将会给出一个小型音乐播放器插件APlayer.js的使用例子.关于APlayer.js的具体介绍和Github地址,可以参考: https://github.com/MoePlayer/A ...
- Ubuntu 安装 JDK8 的两种方式
ubuntu 安装jdk 的两种方式: 1:通过ppa(源) 方式安装. 2:通过官网下载安装包安装. 这里推荐第1种,因为可以通过 apt-get upgrade 方式方便获得jdk的升级 使用pp ...
- Win10一周年纪念版,瞧一瞧Linux子系统
Bash Bash是一个命令处理器,通常运行于文本窗口中,并能执行用户直接输入的命令.Bash还能从文件中读取命令,这样的文件称为脚本.和其他Unix shell 一样,它支持文件名替换(通配符匹配) ...
- [android] 服务的生命周期(混合方式)
绑定服务:可以调用服务里面的方法, 如果调用者activity销毁了,服务也会跟着销毁 单独解除绑定的时候,服务也会被销毁 开启服务:不可以调用服务里面的方法 如果调用者activity退出了,服务还 ...