楔子
hadoop权威指南,用户自定义函数
12.8 用户定义函数
如何需要的查询无法使用hive提供的内置函数来表示。通过写“用户自定义函数(UDF)”,hive可以方便地插入用户写的处理代码并在查询中调用他们。
UDF必须用Java语言编写,hive本身也是java写的。
hive中有三种UDF:(普通)UDF,用户自定义聚集函数 UDAF,以及用户定义表生成函数 UDTF。它们所接受的输入和产生的输出的数据行的数量是不同的。
- UDF操作作用于单个数据行,且产生一个数据行作为输出。大多数函数属于这一类。
- UDAF接受多个输入数据行,并产生一个输出数据行。想cout和max这样的函数都是聚集函数
- UDTF操作作用于单个数据行,且产生多个数据行——一个表——作为输出
和其他两种类型相比,表生成函数的知名度较低。
12.8.1 写UDF
一个UDF必须满足下面两个条件
-
一个UDF必须是 org.apache.hadoop.hive.ql.exec.UDF的子类
-
一个UDF必须至少实现了evaluate()方法
evaluate()方法不是由接口定义的,因为它可接受的参数的个数,他们的数据类型及返回值的数据类型都不确定。hive会检查UDF,看能找到和函数调用相匹配的evaluate()方法。
在hive中使用UDF,需要编译后的java类打包成一个jar文件,并在hive中注册这个文件。
add jar /path/hive-examples.jar
# 为这个java类名起一个别名
create temporary function strip as 'com.example.hive.strip'
# 使用函数
select strip('bee') from dummy;
这里的temporary关键字强调了这样的事实:UDF只是为了这个hive会话过程定义的。事实上,这意味着你需要在每个脚本的最前面添加jar文件或自定义函数,或者在主目录创建包含这些命令的.hiverc文件,以使得这些UDF会在每个hive会话开始时运行。
12.8.2 写UDAF
聚集函数比普通的UDF难写。因为值是在块内进行聚集的(这些块可能分布在很多的的map或reduce任务中),从而实现时能够把部分的聚集值组合成最终结果。
UDAF必须是org.apache.hadoop.hive.ql.exec.UDAF的子类,且包含一个或多个嵌套的,实现了org.apache.hadoop.hive.ql.UDAFEvaluate的静态类。
.hiverc文件
文件中的 注释就去掉吧 ,如果注释存在报错`FAILED: ParseException line 1:0 character '#' not supported here`
文件放在$HIVE_HOME/conf 里面是全局配置
#在命令行中显示当前数据库名
set hive.cli.print.current.db=true;
#查询出来的结果显示列的名称
set hive.cli.print.header=true;
#启用桶表
set hive.enforce.bucketing=true;
#压缩hive的中间结果
set hive.exec.compress.intermediate=true;
#对map端输出的内容使用BZip2编码/解码器
set mapred.map.output.compression.codec=org.apache.hadoop.io.compress.BZip2Codec;
#压缩hive的输出
set hive.exec.compress.output=true;
#对hive中的MR输出内容使用BZip2编码/解码器
set mapred.output.compression.codec=org.apache.hadoop.io.compress.BZip2Codec;
#让hive尽量尝试local模式查询而不是mapred方式
set hive.exec.mode.local.auto=true;