Hive UDF 快速教程

正文

Step1

首先,我们创建一个目录 udf_test/;
创建子目录org/dennis/udf
在子目录里创建一个MyUpper.java文件。里面内容为:

1
2
3
4
5
6
7
8
9
10
11
12
package org.dennis.udf;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
public final class MyUpper extends UDF {
public Text evaluate(final Text s) {
if (s == null) { return null; }
return new Text(s.toString().toUpperCase());
}
}

Step2

1
2
3
4
javac -cp \
/opt/cloudera/parcels/CDH-6.2.0-1.cdh6.2.0.p0.967373/jars/hive-exec-2.1.1-cdh6.2.0.jar: \
/opt/cloudera/parcels/CDH-6.2.0-1.cdh6.2.0.p0.967373/jars/hadoop-common-3.0.0-cdh6.2.0.jar \
org/dennis/udf/MyUpper.java

这里我们要把依赖的jar包写进来,这里我们依赖hive-exec*.jar 以及 hadoop-common.jar

  • javac -cp 的作用
    1
    2
    3
    4
    5
    javac -cp 指明了.java文件里import的类的位置
    java -cp 指明了执行这个class文件所需要的所有类的包路径-即系统类加载器的路径(涉及到类加载机制)
    路径在linux中用:隔开 在windows中用;隔开

Step3

生成一个jar文件。

1
2
jar -cf myudfs.jar -C . .
会在当前目录下生成myudfs.jar 文件

Step4

第一种方式

进入Hive命令行

1
2
3
4
5
6
7
hive> add jar myudfs.jar;
Added [myudfs.jar] to class path
Added resources: [myudfs.jar]
hive> create temporary function dennisUpper as 'org.dennis.udf.MyUpper';
OK
Time taken: 0.067 seconds
hive>

搞定!

第二种方式

另外,也可以在Hue上点击 setting后,上传对应的jar文件,然后将对应的function name 和 class name也填一下就OK了。
Sample Image Added via Markdown

然后再Hue上执行create temporary function dennisUpper as 'org.dennis.udf.MyUpper'; 注册下对应信息。

Step5

执行SQL,检验一下:

1
select dennisUpper(field) from table;

常见问题

找不到类

有时候我们add jar后,create function时候会出现如下报错:

1
2
3
4
Added resources: [myudfs.jar]
hive> create temporary function dennisUpper as 'org.dennis.udf.MyUpper';
FAILED: Class org.dennis.udf.MyUpper not found
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.FunctionTask

我们可以解压一下jar包检查下:

1
2
unzip myudf.jar -d check_jar
解压到 check_jar目录

如果有的话,check_dir下应该是有这么一个目录文件:
org/dennis/udf/MyUpper.class

reload更新的jar包

我们更新了UDF,重新打个jar包替换掉原来的。但如果要让它生效需要做一些操作:

  1. added a config in hive-site.xml, then restart the hive server.

    1
    2
    3
    4
    <property>
    <name>hive.reloadable.aux.jars.path</name>
    <value>/user/hive/udf</value>
    </property>
  2. deleted the old jar file in HDFS, and upload the new jar file.

  3. DROP TEMPORARY FUNCTION IF EXISTS isstopword;

  4. in hive console, run list jar; to check the local jar files, it would print something like this:

/tmp/83ce8586-7311-4e97-813f-f2fbcec63a55_resources/isstopwordudf.jar
then delete them in your server file system.

  1. create a temp function again.
    create temporary function isstopword as ‘org.dennis.udf.IsStopWord’;

Reference

http://bdlabs.edureka.co/static/help/topics/cm_mc_hive_udf.html#concept_zb2_rxr_lw_unique_1