Hive中自带的函数如(sum、count、split等)正常情况下已经能满足日常需求,但是如果需要更加个性化的函数就得自建。
自建函数分为3中,UDF、UDAF、UDTF。UDF(一进一出 ),UDAF (集合函数 多进一出函数),UDTF (一进多出)。
我们自定义hive的UDF就需要加载Hive的jar包,hive的jar包又需要hadoop的功能,所以又要加载hadoop的jar包。我们使用cdh版本的hadoop和hive,所以还有特殊设置Maven仓库。设置pom.xml
设置版本
<properties>
<hive.version>1.1.0-cdh5.7.0hive.version>
<hadoop.version>2.6.0-cdh5.7.0hadoop.version>
properties>
添加cdh远程仓库地址
<repositories>
<repository>
<id>clouderaid>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/url>
repository>
repositories>
下载对应hadoop和hive的Jar包
<dependencies>
<dependency>
<groupId>org.apache.hadoopgroupId>
<artifactId>hadoop-commonartifactId>
<version>${hadoop.version}version>
dependency>
<dependency>
<groupId>org.apache.hivegroupId>
<artifactId>hive-execartifactId>
<version>${hive.version}version>
dependency>
dependencies>
创建一个Hello的UDF的类,继承UDF。在这个类中去重写evaluate这个方法。做一个例子,实现一个功能,输入一个”xxx”,输出一个”Hello : xxx”。
如果要将在hive使用就要打包成jar包,再导入到hive中使用,可以使用Maven进行package打包。
如果要做成Hive的函数,有临时函数和永久函数,临时函数只能当前窗口有效,别的窗口登入时无效。永久有效,所有登入都能有效。
将生成好的jar包上传到$(HIVE_HOME)/lib/下(连接Mysql的包也在这个下面)
即使添加了jar包到lib库,Hive也没法识别,必须手动加入。
add jar /home/hadoop/app/hive-1.1.0-cdh5.7.0/lib/UDF-1.0.jar;
查看下是否导入
list jars;
现在Hive中创建函数名,你才能用,不然不能自动识别。
CREATE TEMPORARY FUNCTION sayHello AS 'com.test.HelloUDF';
检测一下有没有sayHello
show functions;
select sayhello("justTest") from dual;
我在多个窗口设置临时函数,但是每次都要导入Jar包非常麻烦,其实很好解决。
为了防止每个窗口都要导入相同的jar包,只需要在$HIVE_HOME下创建一个文件夹auxlib,
将需要导入的jar包放在里面,每次会话就回导入该地址下的jar包。
上述方法只是临时或者当前窗口有效,如果希望每一个窗口都有效就要设置成永久函数。
自建的永久函数是要注册到meta中的,这样就不用每个session去创建临时函数。
自建的永久函数的jar包是要求路径在hdfs的,所以所需要上传到HDFS上。
CREATE FUNCTION saymyHello AS 'com.test.HelloUDF'
USING JAR 'hdfs://hadoop001:9000/lib/UDF-1.0.jar';
检验一下
list jars;
show functions;
以上这个hdfs 9000端口是hadoop配置中的hadoop/core-site.xml 里fs.defaultFS的参数。
前面这个default是指创建函数当前这个数据库名称,当Hive切换到test这个database中时,创建函数前缀就是test。
还有一种永久就是写入Hive的源码中,在编译安装。继承UDF后实现类的代码,然后Functionregistry注册一下。