大数据入门教程系列之Hive内置函数及自定义函数
本篇文章主要介绍Hive内置函数以及自定义UDF函数和UDFT函数,自定义UDF函数通过一个国际转换中文的例子说明。
操作步骤:
①、准备数据和环境
②、演示Hive内置函数
③、自定义UDF函数编写、演示
详细步骤:
一、准备数据和环境(需启动Hadoop)
注:环境和程序基于上一篇java api操作hive:大数据入门教程系列之Hive的Java API 操作
ctrl+l可以清楚窗口操作的命令
1、创建表
create table teacher(
id int,
name string,
sex string,
age int,
nationality string
)
row format delimited fields terminated by ',';
2、准备数据
vim teacher.txt
1,zhangsan,man,23,CN
2,lisi,woman,33,HK
3,wangwu,man,18,BRA
3、插入数据,执行插入数据有点慢,等待即可
load data local inpath '/home/hadoop/teacher.txt' into table teacher;
插入后查询:
select * from teacher;
二、hive内置函数
1、使用如下命令查看当前hive版本支持的所有内置函数
show functions;
2、可以使用如下命令查看某个函数的使用方法及作用,比如查看 and函数
desc function and;
3、如果想要查看更为详细的信息加上extended参数
desc function extended and;
4、演示小写转大写,查询老师把名字转大写
select id,upper(name),sex,age from teacher;
三、自定义UDF函数
虽然hive中为我们提供了很多的内置函数,但是在实际工作中,有些情况下hive提供的内置函数无法满足我们的需求,就需要我们自己来手动编写,所以就有了自定义函数 UDF。
UDF分为三种,分别如下
(1).UDF(User-Defined-Function),一进一出(输入一行,输出一行),比如:upper()、lowser()等。
(2).UDAF(User-Defined Aggregation Funcation),多进一出(输入多行,输出一行),比如:avg()、sum()等。
(3).UDTF(User-Defined Table-Generating Functions),一进多出(输入一行,输出多行),比如:collect_set()、collect_list()等。
官方文档:https://cwiki.apache.org/confluence/display/Hive/HivePlugins
1、使用自定义函数需要引入hive-exec的依赖
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>2.3.0</version>
</dependency>
2、UDF编程模型:
(1).继承 org.apache.hadoop.hive.ql.exec.UDF
(2).实现 evaluate() 方法
实现需求:自定义UDF函数,转换国籍为中文
比如:输入CN,输出中国大陆
代码如下:
package udf;
import org.apache.hadoop.hive.ql.exec.UDF;
import java.util.HashMap;
import java.util.Map;
import org.apache.hadoop.io.Text;
/**
* UDF自定义函数国籍转换
* Created by zhoujh on 2018/10/18.
*/
public class UDFNationality extends UDF {
//我们要实现的业务逻辑非常简单,就是传过来一个英文的国家名,然后返回一个中文,它们的映射关系肯定事先就定义好了,
//不可能等到调用的时候了才建立映射关系。
public static Map<String,String> nationMap=new HashMap<String,String>();
static {
nationMap.put("CN", "中国");
nationMap.put("HK", "香港");
nationMap.put("BRA", "巴西");
}
//之所以使用Text作为返回值是因为这个方法是要在HDFS上运行的,HDFS上没有String类型,取而代之的是Text,因此我们需要使用Text作为返回值。
Text text=new Text();
//重写UDF,就是要写evaluate方法,注意方法名一定得是这个。这个方法是非常灵活的,参数可以有多个,返回值如果想要多个的话,可以封装成一个对象。
public Text evaluate(Text nation){
//先得到传过来的英文的国家名
String nation_e=nation.toString();
//根据英文名得到中文名
String nation_str=nationMap.get(nation_e);
if(nation_str==null){
//如果得到的值是null,说明没有对应的映射关系,我们就输出默认中国人
text.set("中国人");
return text;
}
text.set(nation_str);
return text;
}
}
3、自定义函数有4种使用方式,下面分别介绍
①、临时函数,只能在当前客户端使用
一、将我们刚刚编写完成的代码,打成jar
二、先使用xftp上传到服务器,再将jar包上传到hive
三、把jar添加到hive
add jar /home/hadoop/java-api-hive-1.0-SNAPSHOT.jar;
四、创建函数
create temporary function cvnationality as 'udf.UDFNationality';
五、查看创建的函数cvnationality
show functions;
六、查看函数cvnationality的详细信息
这里可以看到你java类里面的@Description注解我没写
七、使用函数
select id,name,sex,age,cvnationality(nationality) from teacher;
②、临时函数,只能在当前客户端使用
在$HIVE_HOME下新建目录auxlib,将jar拷贝到该目录下,重启hadoop
创建函数cvnationality
查看创建的函数,同上
使用函数,效果同上
select id,name,sex,age,cvnationality(nationality) from teacher;
③、永久函数,创建后可以在任意客户端使用,建议使用
一、上传jar到hdfs
hadoop fs -put java-api-hive-1.0-SNAPSHOT.jar /libs
二、创建函数 cvnationality2
create function cvnationality2 as 'udf.UDFNationality' using jar 'hdfs://node1:9000/libs/java-api-hive-1.0-SNAPSHOT.jar';
注意:创建完function之后,通过show functions并没有看到我们自定义的函数cvnationality2,但是可以使用
三、使用函数,效果同上
select id,name,sex,age,default.cvnationality2(nationality) from teacher;
④、永久函数,将自定义函数集成到hive源码中
使用这种方式需要修改hive的源代码,集成到hive源码后,hive启动后就可以使用,不用再向hive中注册函数,相当于一个hive的内置函数。如果公司有自己的大数据框架版本,建议使用这种方式。
一、从官网下载hive源码,笔者使用的版本为2.3.0,http://apache.fayea.com/hive/
二、下载后解压
tar -zxvf apache-hive-2.3.0-src.tar.gz
将自定义UDF函数继承到Hive源码中,需要如下三个步骤
三、上传文件
把GenericUDFHello.java类上传到如下目录,并修改包名
四、配置FunctionRegistry类
hive 中有一个非常重要的类FunctionRegistry,我们需要将自己自定义的函数在这个类中配置,引入我们自定义函数类GenericUDFHello
注册自定义函数类GenericUDFHello,输入static { 搜索,在静态代码块中注册我们编写的自定义函数,这里面都是hive的所有内置函数,添加如下代码
五、编译 Hive 源码
cd apache-hive-2.3.0-src
mvn clean package -Phadoop-2,dist -DskipTests
编译过程教程,请耐心等待,编译完成后,hive会生成一个压缩包,解压配置后就可以使用,hive压缩包存放的路径是apache-hive-2.3.0-src/packaging/target
使用函数hello(效果同上)