45、sparkSQL UDF&UDAF
一、UDF
1、UDF
UDF:User Defined Function。用户自定义函数。
2、scala案例
package cn.spark.study.sql import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.sql.SQLContext
import org.apache.spark.sql.Row
import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.types.StructField
import org.apache.spark.sql.types.StringType object UDF {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setMaster("local").setAppName("UDF")
val sc = new SparkContext(conf)
val sqlContext = new SQLContext(sc) // 构造模拟数据
val names = Array("Leo", "Marry", "Jack", "Tom")
val namesRDD = sc.parallelize(names, 5)
val namesRowRDD = namesRDD.map(name => Row(name))
val structType = StructType(Array(StructField("name", StringType, true)))
val namesDF = sqlContext.createDataFrame(namesRowRDD, structType) // 注册一张names表
namesDF.registerTempTable("names") // 定义和注册自定义函数
// 定义函数:自己写匿名函数
// 注册函数:SQLContext.udf.register()
// UDF函数名:strLen; 函数体(匿名函数):(str: String) => str.length()
sqlContext.udf.register("strLen", (str: String) => str.length()) // 使用自定义函数
sqlContext.sql("select name, strLen(name) from names")
.collect()
.foreach(println) }
}
3、java案例
package cn.spark.study.sql; import java.util.ArrayList;
import java.util.List; import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.api.java.function.VoidFunction;
import org.apache.spark.sql.DataFrame;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.RowFactory;
import org.apache.spark.sql.SQLContext;
import org.apache.spark.sql.api.java.UDF1;
import org.apache.spark.sql.types.DataTypes;
import org.apache.spark.sql.types.StructField;
import org.apache.spark.sql.types.StructType; public class UDF {
public static void main(String[] args) {
SparkConf conf = new SparkConf().setAppName("UDFJava").setMaster("local");
JavaSparkContext sparkContext = new JavaSparkContext(conf);
SQLContext sqlContext = new SQLContext(sparkContext); List<String> stringList = new ArrayList<String>();
stringList.add("Leo");
stringList.add("Marry");
stringList.add("Jack");
stringList.add("Tom");
JavaRDD<String> rdd = sparkContext.parallelize(stringList);
JavaRDD<Row> nameRDD = rdd.map(new Function<String, Row>() { private static final long serialVersionUID = 1L; @Override
public Row call(String v1) throws Exception {
return RowFactory.create(v1);
}
}); List<StructField> fieldList = new ArrayList<StructField>();
fieldList.add(DataTypes.createStructField("name", DataTypes.StringType, true));
StructType structType = DataTypes.createStructType(fieldList);
DataFrame dataFrame = sqlContext.createDataFrame(nameRDD, structType); dataFrame.registerTempTable("name");
sqlContext.udf().register("strLen", new UDF1<String, Integer>() { private static final long serialVersionUID = 1L; @Override
public Integer call(String s) throws Exception {
// TODO Auto-generated method stub
return s.length();
} }, DataTypes.IntegerType); sqlContext.sql("select name, strLen(name) from name").javaRDD().
foreach(new VoidFunction<Row>() { private static final long serialVersionUID = 1L; @Override
public void call(Row row) throws Exception {
System.out.println(row);
}
}); }
}
二、UDAF
1、概述
UDAF:User Defined Aggregate Function。用户自定义聚合函数。是Spark 1.5.x引入的最新特性。 UDF,其实更多的是针对单行输入,返回一个输出,这里的UDAF,则可以针对一组(多行)输入,进行聚合计算,返回一个输出,功能更加强大
使用: 1. 自定义类继承UserDefinedAggregateFunction,对每个阶段方法做实现 2. 在spark中注册UDAF,为其绑定一个名字 3. 然后就可以在sql语句中使用上面绑定的名字调用
2、scala案例
统计字符串次数的例子,先定义一个类继承UserDefinedAggregateFunction:
package cn.spark.study.sql import org.apache.spark.sql.expressions.UserDefinedAggregateFunction
import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.types.DataType
import org.apache.spark.sql.expressions.MutableAggregationBuffer
import org.apache.spark.sql.Row
import org.apache.spark.sql.types.StructField
import org.apache.spark.sql.types.StringType
import org.apache.spark.sql.types.IntegerType /**
* @author Administrator
*/
class StringCount extends UserDefinedAggregateFunction { // inputSchema,指的是,输入数据的类型
def inputSchema: StructType = {
StructType(Array(StructField("str", StringType, true)))
} // bufferSchema,指的是,中间进行聚合时,所处理的数据的类型
def bufferSchema: StructType = {
StructType(Array(StructField("count", IntegerType, true)))
} // dataType,指的是,函数返回值的类型
def dataType: DataType = {
IntegerType
} def deterministic: Boolean = {
true
} // 为每个分组的数据执行初始化操作
def initialize(buffer: MutableAggregationBuffer): Unit = {
buffer(0) = 0
} // 指的是,每个分组,有新的值进来的时候,如何进行分组对应的聚合值的计算
def update(buffer: MutableAggregationBuffer, input: Row): Unit = {
buffer(0) = buffer.getAs[Int](0) + 1
} // 由于Spark是分布式的,所以一个分组的数据,可能会在不同的节点上进行局部聚合,就是update
// 但是,最后一个分组,在各个节点上的聚合值,要进行merge,也就是合并
def merge(buffer1: MutableAggregationBuffer, buffer2: Row): Unit = {
buffer1(0) = buffer1.getAs[Int](0) + buffer2.getAs[Int](0)
} // 最后,指的是,一个分组的聚合值,如何通过中间的缓存聚合值,最后返回一个最终的聚合值
def evaluate(buffer: Row): Any = {
buffer.getAs[Int](0)
} }
然后注册并使用它:
package cn.spark.study.sql import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.sql.SQLContext
import org.apache.spark.sql.Row
import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.types.StructField
import org.apache.spark.sql.types.StringType /**
* @author Administrator
*/
object UDAF { def main(args: Array[String]): Unit = {
val conf = new SparkConf()
.setMaster("local")
.setAppName("UDAF")
val sc = new SparkContext(conf)
val sqlContext = new SQLContext(sc) // 构造模拟数据
val names = Array("Leo", "Marry", "Jack", "Tom", "Tom", "Tom", "Leo")
val namesRDD = sc.parallelize(names, 5)
val namesRowRDD = namesRDD.map { name => Row(name) }
val structType = StructType(Array(StructField("name", StringType, true)))
val namesDF = sqlContext.createDataFrame(namesRowRDD, structType) // 注册一张names表
namesDF.registerTempTable("names") // 定义和注册自定义函数
// 定义函数:自己写匿名函数
// 注册函数:SQLContext.udf.register()
sqlContext.udf.register("strCount", new StringCount) // 使用自定义函数
sqlContext.sql("select name,strCount(name) from names group by name")
.collect()
.foreach(println)
} }
45、sparkSQL UDF&UDAF的更多相关文章
- 简述UDF/UDAF/UDTF是什么,各自解决问题及应用场景
UDF User-Defined-Function 自定义函数 .一进一出: 背景 系统内置函数无法解决实际的业务问题,需要开发者自己编写函数实现自身的业务实现诉求. 应用场景非常多,面临的业务不同导 ...
- 45、[源码]-Spring容器创建-执行BeanFactoryPostProcessor
45.[源码]-Spring容器创建-执行BeanFactoryPostProcessor 5.invokeBeanFactoryPostProcessors(beanFactory);执行BeanF ...
- Spark(十三)【SparkSQL自定义UDF/UDAF函数】
目录 一.UDF(一进一出) 二.UDAF(多近一出) spark2.X 实现方式 案例 ①继承UserDefinedAggregateFunction,实现其中的方法 ②创建函数对象,注册函数,在s ...
- [转]HIVE UDF/UDAF/UDTF的Map Reduce代码框架模板
FROM : http://hugh-wangp.iteye.com/blog/1472371 自己写代码时候的利用到的模板 UDF步骤: 1.必须继承org.apache.hadoop.hive ...
- 2、Hive UDF编程实例
Hive的UDF包括3种:UDF(User-Defined Function).UDAF(User-Defined Aggregate Function)和UDTF(User-Defined Tabl ...
- Hive 自定义函数 UDF UDAF UDTF
1.UDF:用户定义(普通)函数,只对单行数值产生作用: 继承UDF类,添加方法 evaluate() /** * @function 自定义UDF统计最小值 * @author John * */ ...
- 【转】HIVE UDF UDAF UDTF 区别 使用
原博文出自于:http://blog.csdn.net/longzilong216/article/details/23921235(暂时) 感谢! 自己写代码时候的利用到的模板 UDF步骤: 1 ...
- SparkSQL之UDAF使用
1.创建一个类继承UserDefinedAggregateFunction类. ------------------------------------------------------------ ...
- sparksql udf的运用----scala及python版(2016年7月17日前完成)
问:udf在sparksql 里面的作用是什么呢? 答:oracle的存储过程会有用到定义函数,那么现在udf就相当于一个在sparksql用到的函数定义: 第二个问题udf是怎么实现的呢? regi ...
随机推荐
- iTextSharp 不适用模板 代码拼接PDF
/// <summary> /// 打印移库单 /// </summary> /// <param name="guid"></param ...
- Mycat分布式数据库架构解决方案--Server.xml详解
echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.--这才是真正的堪称强大!!! 该文件 ...
- VBA文本文件(二十)
还可以读取Excel文件,并使用VBA将单元格的内容写入文本文件.VBA允许用户使用两种方法处理文本文件 - 文件系统对象(FSO) 使用Write命令 文件系统对象(FSO) 顾名思义,FSO对象帮 ...
- linux 下 shell脚本报错:-bash: ./build.sh: /bin/sh^M: bad interpreter: No such file or directory
主要原因是build.sh是在windows下编辑然后上传到linux系统里执行的..sh文件的格式为dos格式.而linux只能执行格式为unix格式的脚本. 我们可以通过vi编辑器来查看文件的fo ...
- 手写DAO框架(六)-框架使用示例
一.引入pom <dependency> <groupId>me.lovegao</groupId> <artifactId>gdao</arti ...
- TR-银行通信相关文档
DMEE配置指南: https://wenku.baidu.com/view/06790649767f5acfa1c7cd73.html F110 DMEE配置: https://wenku.baid ...
- SYBASE扩充日志段空间
有时候日志段空间满了使用下列语句也无济于事,又不能直接重启库,就加空间应急,dump tran QAS with truncate_only dump tran QAS with no_log sp_ ...
- MongoDB/聚合/MR
管道与Aggregation: 文档结构如下: { "_id" : 1, "item" : "abc", "price" ...
- 华为云和开源Istio运维管理对比样例应用部署
前言 在公有云方面,华为云已经率先将 Istio 作为产品投入到公有云中进行商业应用中,保持和开源istio高度兼容,做了商业化的运维管理界面,同时进行了性能优化.这里我们做一次验证测试. Booki ...
- spark HMM
Scala实现的: https://github.com/skrusche63/spark-intent/tree/master/src/main/scala/de/kp/scala/hmm http ...