Hive 9. 用户定义的方法(UDF-User-Defined Functions)
来源:互联网 发布:重庆网站外包优化 编辑:程序博客网 时间:2024/05/29 15:26
用户自定义方法(函数)
本文为Hadoop 权威指南第四版(英文原版),Hive 章节的部分翻译。仅限交流使用。
Henvealf/译
有时候 Hive 提供的函数并不能满足我们的需求,Hive 允许用户自己自定义(UDF),可插拔的加入到 Hive 中去使用。
主要是用 Java 写,也可以使用其他语言,就是使用流的来实现,这里不做讨论。
UDF 一共有三种类型:UDF(User-Defined Function), UDFA(User-Defined aggregate function,用户自定义的聚合函数 ),UDTF(User-Defined table-generating function,用户自定义的生成表的函数) 。
UDF 是操作一行而生成一行数据。
UDFA 是操作多行而最终生成一行 (也就是所谓的聚合函数)。
UDTA 是操作一行而生成多行(也就是生成表)。
表生成函数确实是很少听过,他在 Hive 中主要是以集合类型(例如Array)作为参数的函数,比如将一个数组中的每个值取出,每个值各自单独成一列,即是一列变多列,容易理解,就不举例子了。
写一个 UDF
有一个小栗子,写一个函数,功能与 trim 类似,去除字符串开始与结束的空格。这里我们还可以指定要去除的字符串。
packge com.henvealf;import org.apache.commons.lang.StringUtils;import org.apache.hadoop.hive.ql.exec.UDF;import org.apache.hadoop.io.Text;public class Strip extends UDF { private Text result = new Text(); public Text evaluate(Text str) { if(str == null) { return null; } result.set(StringUtils.strip(str.toString())); return result; } public Text evaluate(Text str, String stripChars) { if(str == null) { return null; } result.set(StringUtils.strip(str.toString(),stripChars)); return result; }}
UDF 的编写必须符合下面两个条件:
- 必须是 org.apache.hadoop.hive.ql.exec.UDF 的子类;
至少实现一个 evaluate() 方法。
解释: evaluater 求值程序
evaluate() 方法并没有使用接口来定义,因为他需要有任意数量和任意类型的参数,并能够返回任意类型的返回值。Hive在函数被调用时通过反射来寻找要被调用的方法。
Hive 中操作 UDF
创建一个方法:
Create Function strip 'com.henvealf.Strip'Using Jar '/user/henvealf/udf/udf.jar'
创建一个临时方法,其只在当前会话中生效:
Add Jar /user/henvealf/udf/udf.jar;Create Temporary Function strip 'com.henvealf.Strip'
删除方法:
Drop Function strip;
注意,如果 Hive 在分布模式下,这里的路径就是 DFS 的路径,否则就是本地路径。
编写 UDAF
UDAF(聚合函数) 比 UDF 复杂许多。下面这个有一个求最大值的例子:
import org.apache.hadoop.hive.ql.exec.UDF;import org.apache.hadoop.hive.ql.exec.UDAFEvaluator;public class Maximum extends UADF { public static class MaximumIntUDAFEvaluator implements UDAFEvaluator { private IntWritable result; public void init() { result = null; } public boolean iterate (IntWritable value) { if(value == null) { return true; } if(result == null) { result = new IntWritable(value.get()); } else { result.set(Max.max(result.get(), value.get())); } return true; } public IntWritable terminatePartial() { return result; } public boolean merge(IntWritable other) { return iterate(other); } public IntWritable terminate() { return result; } }}
UDAF 和 UDF 相比较,可以发现其 Evaluator 由一个方法升级成了一个类,且这个类必须实现 org.apache.hadoop.hive.ql.exec.UDAFEvaluator 接口, 接口中有需要实现的抽象许多方法,也就是说 Hive 调用该聚合函数的时候是联合这些方法来完成函数任务,这里介绍一下:
init()
init() 用于初始化每个求值器(Evaluator),以及重新设置他的状态。因为一个聚合函数中有许多的 Evaluator,在不同的时刻或并发,或顺序工作。在本例中,将记录最终结果用的 result 设置为空,这里的空(null)对应数据库中的 NULL.
iterate()
iterate() 每被调用一次,都会有一个新的值被聚合。这时求值器就应该有一个内置的标识(这里就是 result)来记录并随时更新值。iterate() 的参数类型要与函数的输入格式相同。返回值为 true 意味着输入值可用。
terminatePartial()
负责对每个局部聚合的结果返回一个值。这个方法必须返回一个封装了标志的聚合体对象(这里是 result )。
merge()
这个方法在每个局部聚合求值器执行完成后调用(和 reducer 很像啊),用来合并他们的输出,这个方法得到一个对象,且必须与 terminatePartial() 的返回值相同。
terminate()
这个方法在所有的工作完成后做收尾,做最后的聚合并返回最后结果。
hive> Create Temparary Function maximum As 'com.henvealf.Maximum'hive> Select * maximum(temperature) From record;
看下图:
一个复杂点的 UDAF
自己看看代码吧,有注释:
public class Mean extends UDAF { public static class PartialResult { double sum; int count; } public static class MeanUDAFEvaluator implements UDAFEvaluator { private PartialResult partialResult; // 初始化,实例化字段partialResult; // 对每个局部输入调用一次。 // 每个 merge 开始时候调用一次。 public void init() { partialResult = new ParagraphView(); } // 对每个文件的double 求和,并计数。会被调用多次。 public boolean iterate( DoubleWritable inputValue ) { if ( inputValue == null ) { return true; } partialResult.sum += inputValue.get(); partialResult.count ++; return true; } // 终止局部处理后的操作,直接返回 partialResult。 // iterate 处理完一个局部输入后调用。 public PartialResult terminatePartial() { return partialResult; } // 合并各个局部操作的结果 // 有几个局部输出就调用几次。 public boolean merge( PartialResult other ) { if( other == null ) { return true; } partialResult.sum += other.sum; partialResult.count += other.count; return true; } // 在最最最后调用。 public DoubleWritable terminate() { return new DoubleWritable(partialResult.sum / partialResult.count); } }}
End!!!
- Hive 9. 用户定义的方法(UDF-User-Defined Functions)
- hive的UDF 函数(User-Defined-Function)
- hive UDF(User-Defined-Function) 实战
- Hive Operators and User-Defined Functions (UDFs)
- Hive Operators and User-Defined Functions (UDFs) hive 日期函数
- UDF (User-defined Function)
- User Defined Functions
- iOS 在user defined runtime attributes(用户定义的运行时属性)改变UI
- 自定义函数。用户自定义函数(User Defined Functions)SQL Server 2000
- Transact SQL User Defined Functions
- Table-Valued User-Defined Functions
- HIVE 用户自定义函数(UDF)
- hive的UDF (2)
- 用户自定义类型(User-defined Type)参数的传递
- MYSQL用户定义函数(UDF)
- Hive部署UDF的四种方法
- Hive UDF调试打印的方法
- SQL-UDF:GetMidStr User Defined Function
- QWT编译以及交叉编译的问题
- hdu2057 A + B Again
- Oracle忘记用户名密码 或 账户锁定
- Android中通过Picasso来加载网络图片,并通过ListView显示出来。
- Java中synchronized的用法
- Hive 9. 用户定义的方法(UDF-User-Defined Functions)
- sourceTree一直提示输入密码问题
- NodeJS的桌面应用开发 Electron
- iOS开发之duplicate symbols for architecture x86_64错误
- 一个web请求的过程
- 类的简单强制转换
- Linux的/proc伪文件系统
- T-SQL查询进阶--理解SQL SERVER中的分区表
- mac终端命令大全