Hive自定义UDF函数

1.简介

  • UDF函数分类
  • UDF : User-Defined Function 一进一出,eg. substr
  • UDAF : User-Defined Aggregation Function 多进一出,eg.
  • UDTF : User-Defined Table-Generating Function 一进多出,eg.

2.非源码级别自定义UDF函数

2.1.准备自定义函数

2.1.1.编写函数类

AddPrefixUDF.java

package com.cll.bigdata.hive.udf;
import org.apache.commons.lang.math.RandomUtils;
import org.apache.hadoop.hive.ql.exec.UDF;
/**
 * @ClassName AddPrefixUDF
 * @Description 添加前缀  udf
 * @Author cll
 * @Date 2019-09-18 21:58
 * @Version 1.0
 **/
public class AddPrefixUDF extends UDF {
    /**
     * 给字符串添加前缀
     * @param value  字符串
     * @return
     */
    public String evaluate(String value){
        int num = RandomUtils.nextInt(10);
        return num + "_" + value;
    }
}

2.1.2.打包上传并至服务器

2.2.注册函数

注册函数分为两种方式:

  • 临时 : 只在当前hive窗口有效,窗口关闭,函数即被移除

  • 永久 : 当前hive窗口关闭,重新打开也可以使用

2.2.1.临时

格式 :CREATE TEMPORARY FUNCTION 函数名(自定义) AS “自定义函数的全路径”;

# 添加jar包
hive (cll_ba)> add jar /home/hadoop/lib/cll-hadoop-1.0.jar;

# 创建临时方法(窗口关闭该函数就会被移除)
hive (cll_ba)> CREATE TEMPORARY FUNCTION add_prefix AS "com.cll.bigdata.hive.udf.AddPrefixUDF";

# 原始数据
hive (cll_ba)> select * from access_log;
OK
access_log.uid  access_log.pid
user1   a
user2   b
user3   c
user1   b
user3   a
user3   c
user2   c
user1   a
user1   c

# 使用函数 可以看出 uid的值前面已经拼接了随机数
hive (cll_ba)> select add_prefix(uid),pid from  access_log;
OK
_c0     pid
0_user1 a
8_user2 b
4_user3 c
2_user1 b
5_user3 a
7_user3 c
7_user2 c
6_user1 a
7_user1 c
Time taken: 0.142 seconds, Fetched: 9 row(s)

2.2.2.永久

需要先把jar包上传至hdfs

格式 :CREATE FUNCTION 函数名(自定义) AS “自定义函数的全路径” USING JAR “jar包的hdfs路径”;

hive (cll_ba)> CREATE FUNCTION add_prefix AS "com.cll.bigdata.hive.udf.AddPrefixUDF"
                   > USING JAR "hdfs://hadoop000:9000/hadoop/jar/cll-hadoop-1.0.jar";
converting to local hdfs://hadoop000:9000/hadoop/jar/cll-hadoop-1.0.jar
Added [/tmp/71a20550-93e2-435a-a4c3-438a5d29678b_resources/cll-hadoop-1.0.jar] to class path
Added resources: [hdfs://hadoop000:9000/hadoop/jar/cll-hadoop-1.0.jar]
OK
Time taken: 0.294 seconds
hive (cll_ba)> select add_prefix(uid),pid from  access_log;
OK
_c0     pid
2_user1 a
0_user2 b
1_user3 c
8_user1 b
8_user3 a
1_user3 c
0_user2 c
1_user1 a
9_user1 c
Time taken: 0.35 seconds, Fetched: 9 row(s)

3.源码级别自定义UDF函数

说明:改动hive源码,需要重新编译源码并部署

  • 添加自定义函数

新增 UDFAddPrefix.java

package org.apache.hadoop.hive.ql.udf;

import org.apache.commons.lang.math.RandomUtils;
import org.apache.hadoop.hive.ql.exec.UDF;

/**
 * @ClassName UDFAddPrefix
 * @Description 添加前缀
 * @Author cll
 * @Date 2019-09-27 14:02
 * @Version 1.0
 **/
public class UDFAddPrefix extends UDF {

    public String evaluate(String fieldValue){
        int randomNum = RandomUtils.nextInt(5);
        return randomNum + "_" + fieldValue;
    }

}

修改:org.apache.hadoop.hive.ql.exec.FunctionRegistry.java

⚠️ 如果直接是在linux上面修改的源码,切记别忘了手动import UDFAddPrefix

static {
  system.registerUDF("add_prefix_new", UDFAddPrefix.class, false);
}
  • 编译
mvn clean package -DskipTests -Phadoop-2 -Pdist
  • 配置

1.拷贝一份conf下面的hive-env.sh.template hive-env.sh 并修改hadoop_home配置

# Set HADOOP_HOME to point to a specific hadoop install directory
HADOOP_HOME=/home/hadoop/app/hadoop

2.新增一个hive-site.sh

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>

	<!-- JDBC URL -->
	<property>
        <name>javax.jdo.option.ConnectionURL</name>
        <value>jdbc:mysql://localhost:3306/hive_compile_metadata?createDatabaseIfNotExist=true&amp;characterEncoding=UTF-8&amp;useSSL=false</value>
    </property>

	<!-- JDBC DRIVER -->
	<property>
      	<name>javax.jdo.option.ConnectionDriverName</name>
        <value>com.mysql.jdbc.Driver</value>
   	</property>

	<!-- JDBC USERNAME -->
	<property>
  		<name>javax.jdo.option.ConnectionUserName</name>
      	<value>root</value>
    </property>

	<!-- JDBC PASSWORD -->
	<property>
		<name>javax.jdo.option.ConnectionPassword</name>
		<value>123456</value>
	</property>

	<!-- Hive命令行显示当前数据库名 -->
	<property>
	    <name>hive.cli.print.current.db</name>
	    <value>true</value>
	</property>

	<!-- Hive命令行显示列名 -->
    <property>
        <name>hive.cli.print.header</name>
        <value>true</value>
    </property>

</configuration>
  • 配置环境变量
## hive
export HIVE_HOME=/home/hadoop/app/hive
export PATH=$HIVE_HOME/bin:$PATH
  • 启动
# 启动
[hadoop@hadoop000 hive-compile]$ hive

# 查看函数  已经出现了自定义的函数
hive> show functions;
OK
...
add_prefix_new
...
  • 测试自定义函数
# 建库
hive> create database cll_ba;
hive> use cll_ba;

# 建表
create table access_log(
  uid string,
  pid string
) row format delimited fields terminated by '\t';

# 准备测试数据
[hadoop@hadoop000 data]$ vi access_log.txt
user1   a
user2   b
user3   c
user1   b
user3   a
user3   c
user2   c
user1   a
user1   c

# 加载数据
hive> LOAD DATA LOCAL INPATH '/home/hadoop/data/access_log.txt' into table cll_ba.access_log;

# 测试函数
hive> select add_prefix_new(uid) from access_log;
OK
1_user1
3_user2
3_user3
2_user1
3_user3
3_user3
3_user2
0_user1
3_user1
Time taken: 0.098 seconds, Fetched: 9 row(s)

完成!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值