案例解析丨 Spark Hive 自定义函数应用
摘要:Spark目前支持UDF,UDTF,UDAF三种类型的自定义函数。
1. 简介
Spark目前支持UDF,UDTF,UDAF三种类型的自定义函数。UDF使用场景:输入一行,返回一个结果,一对一,比如定义一个函数,功能是输入一个IP地址,返回一个对应的省份。UDTF使用场景: 输入一行,返回多行(hive),一对多, 而sparkSQL中没有UDTF, spark中用flatMap即可实现该功能。UDAF: 输入多行,返回一行, aggregate(主要用于聚合功能,比如groupBy,count,sum), 这些是spark自带的聚合函数,但是复杂相对复杂。
Spark底层其实以CatalogFunction结构封装了一个函数,其中FunctionIdentifier描述了函数名字等基本信息,FunctionResource描述了文件类型(jar或者file)和文件路径;Spark的SessionCatalog提供了函数注册,删除,获取等一些列接口,Spark的Executor在接收到函数执行sql请求时,通过缓存的CatalogFunction信息,找到CatalogFunction中对应的jar地址以及ClassName, JVM动态加载jar,并通过ClassName反射执行对应的函数。

图1. CatalogFunction结构体

图2. 注册加载函数逻辑
Hive的HiveSessionCatalog是继承Spark的SessionCatalog,对Spark的基本功能做了一层装饰以适配Hive的基本功能,其中包括函数功能。HiveSimpleUDF对应UDF,HiveGenericUDF对应GenericUDF,HiveUDAFFunction对应AbstractGenericUDAFResolve以及UDAF,HiveGenericUDTF对应GenericUDTF

图3. Hive装饰spark函数逻辑
2. UDF
UDF是最常用的函数,使用起来相对比较简单,主要分为两类UDF:简单数据类型,继承UDF接口;复杂数据类型,如Map,List,Struct等数据类型,继承GenericUDF接口。
简单类型实现UDF时,可自定义若干个名字evaluate为的方法,参数和返回类型根据需要自己设置。因为UDF接口默认使用DefaultUDFMethodResolver去方法解析器获取方法,解析器是根据用户输入参数和写死的名字evaluate去反射寻找方法元数据。当然用户也可以自定义解析器解析方法。

图4. 自定义UDF简单示例

图5.默认UDF方法解析器
3. UDAF
UDAF是聚合函数,目前实现方式主要有三种:实现UDAF接口,比较老的简答实现方式,目前已经被废弃;实现UserDefinedAggregateFunction,目前使用比较普遍方式,按阶段实现接口聚集数据;实现AbstractGenericUDAFResolver,实现相对UserDefinedAggregateFunction方式稍微复杂点,还需要实现一个计算器Evaluator(如通用计算器GenericUDAFEvaluator),UDAF的逻辑处理主要发生在Evaluator。
UserDefinedAggregateFunction定义输入输出数据结构,实现初始化缓冲区(initialize),聚合单条数据(update),聚合缓存区(merge)以及计算最终结果(evaluate)。


图6.自定义UDAF简单示例
4. UDTF
UDTF简单粗暴的理解是一行生成多行的自动函数,可以生成多行多列,又被称为表生成函数。目前实现方式是实现GenericUDTF接口,实现2个接口,initialize接口参数校验,列的定义,process接口接受一行数据,切割数据。


图7.自定义UDTF简单示例
案例解析丨 Spark Hive 自定义函数应用的更多相关文章
- hive -- 自定义函数和Transform
hive -- 自定义函数和Transform UDF操作单行数据, UDAF:聚合函数,接受多行数据,并产生一个输出数据行 UDTF:操作单个数据 使用udf方法: 第一种: add jar xxx ...
- Hive自定义函数的学习笔记(1)
前言: hive本身提供了丰富的函数集, 有普通函数(求平方sqrt), 聚合函数(求和sum), 以及表生成函数(explode, json_tuple)等等. 但不是所有的业务需求都能涉及和覆盖到 ...
- hive自定义函数(UDF)
首先什么是UDF,UDF的全称为user-defined function,用户定义函数,为什么有它的存在呢?有的时候 你要写的查询无法轻松地使用Hive提供的内置函数来表示,通过写UDF,Hive就 ...
- hive自定义函数学习
1介绍 Hive自定义函数包括三种UDF.UDAF.UDTF UDF(User-Defined-Function) 一进一出 UDAF(User- Defined Aggregation Funcat ...
- hive自定义函数UDF UDTF UDAF
Hive 自定义函数 UDF UDTF UDAF 1.UDF:用户定义(普通)函数,只对单行数值产生作用: UDF只能实现一进一出的操作. 定义udf 计算两个数最小值 public class Mi ...
- Spark SQL 自定义函数类型
Spark SQL 自定义函数类型 一.spark读取数据 二.自定义函数结构 三.附上长长的各种pom 一.spark读取数据 前段时间一直在研究GeoMesa下的Spark JTS,Spark J ...
- Hive 自定义函数(转)
Hive是一种构建在Hadoop上的数据仓库,Hive把SQL查询转换为一系列在Hadoop集群中运行的MapReduce作业,是MapReduce更高层次的抽象,不用编写具体的MapReduce方法 ...
- Hive 自定义函数
hive 支持自定义UDF,UDTF,UDAF函数 以自定义UDF为例: 使用一个名为evaluate的方法 package com.hive.custom; import org.apache.ha ...
- Hive 自定义函数 UDF UDAF UDTF
1.UDF:用户定义(普通)函数,只对单行数值产生作用: 继承UDF类,添加方法 evaluate() /** * @function 自定义UDF统计最小值 * @author John * */ ...
- Hadoop之Hive自定义函数的陷阱
A left join B, 这个B会连到A. 如<A1,B>, <A2,B>,在处理第一条记录的时候将B.clear(),则第二条记录的B是[]空的这是自定义UDF函数必须注 ...
随机推荐
- Linux 中如何安全地抹去磁盘数据?
哈喽大家好,我是咸鱼 离过职的小伙伴都知道,离职的时候需要上交公司电脑,但是电脑里面有许多我们的个人信息(聊天记录.浏览记录等等) 所以我们就需要先把这些信息都删除,确保无法恢复之后才上交 即有些情况 ...
- Mybatis_plus笔记
Mybatis_plus笔记 在使用mybatis_plus的过程中我们可以明显的感受到他的强大之处.它就像是Mybatis和Jpa的结合体一样,它拥有jpa对单表的各种CRUD操作以及强大的条件构造 ...
- 自定义xunit测试用例的执行顺序
有的时候我们会对程序进行单元测试, 为了测试的效果以及后期的维护, 我一般会将各个测试拆开, 根据需要测试的类分到各个类型中, 不过在实际操作的时候就出现了一些意想不到的问题, 各个测试的执行是乱序的 ...
- Altium Designer中'=SheetNumber'和'=SheetTotal'参数无效的解决方法
出现的问题 图纸没有被自动编号 在Altium中该显示区域被称为Title Block.[这里使用了图纸模板]. 当使用层次化的设计方式时,往往一个工程中若干幅原理图.这时我们需要为原理图进行编号. ...
- Static关键词
在程序中使用static 变量 1. 局部变量 普通局部变量是再熟悉不过的变量了,在任何一个函数内部定义的变量(不加static修饰符)都属于这个范畴.编译器一般不对普通局部变量进行初始化,也就是说它 ...
- .NET8:快速集成Rapid.NET三维控件
.NET8正式版本发布了,AnyCAD Rapid.NET针对.NET8进行了升级和优化.本文以WPF项目为例介绍在.NET8中使用AnyCAD Rapid.NET三维控件. 1 从.NET6升级 若 ...
- 匿名远程启动jenkins的job
安装jenkins插件Build Authorization Token Root job配置中的构建触发器,勾选触发远程构建,输入要用的令牌,如soul 通过jenkins地址调用触发 非参数化jo ...
- 前端解析excel表格
需求如下: 前端拿到表格中的数据,对数据做以下判断,并将拿到的数据转换成以下json格式,传给后端. 具体实现: 下载npm包:npm install xlsx --save 在vue文件中引入依赖: ...
- Vue-cli脚手架下载安装
注意:在下载安装该脚手架之前先安装配置好NodeJS以及镜像源,NodeJS详情可查询文章:NodeJS下载安装 1.cmd中输入以下指令: npm install -g @vue/cli 整个过程中 ...
- LambdaQueryWrapper常用方法
/***附加条件构造器LambdaQueryWrapper常用方法 ---这几个肯定够用了*/wrapper.eq("实体类::查询字段", "条件值"); / ...