官方教程:https://cwiki.apache.org/confluence/display/Hive/HivePlugins
简单使用查看上面官方的文档即可。这里记录一下我使用的实践和一点注意事项。
一 编写udf
这里的需求是写一个udf,用于将经纬度转换成geohash。参数有 经纬度和geohash的精度。
gradle配置
gradle 部分配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| dependencies { compile group: 'ch.hsr', name: 'geohash', version: '1.3.0' compileOnly group: 'org.apache.hive', name: 'hive-exec', version: '2.3.6' }
task fatJar(type: Jar) { baseName = 'hiveFunction' project.fileTree("$buildDir/fatjar/libs").forEach { jarFile -> from zipTree(jarFile ) } with jar destinationDir = file("$buildDir/fatjar") }
task copyToLib(type: Copy) { into "$buildDir/fatjar/libs" from configurations.runtime }
|
UDF类
GeoHashUDF.java 代码如下:
这里需要注意的就是注释的写法,以及异常的处理。
因为在hive执行的过程中,如果udf抛一个异常出来,有可能会导致整个hive sql执行的失败。所以,对于业务异常,应该避免向外抛出。
以本geohash的udf为例,如果给定的经纬度不合法,则可返回用0填充的默认字符串。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import ch.hsr.geohash.GeoHash; import org.apache.hadoop.hive.ql.exec.Description; import org.apache.hadoop.hive.ql.exec.UDF;
import java.util.HashMap; import java.util.Map;
@Description( name = "geohash", value = "_FUNC_(double lat,double lon,int precison) - Returns geohash", extended = "Example:\n > SELECT _FUNC_(\'20.1,111.2,6\') FROM src LIMIT 1;\n \'hello:Facebook\'" ) public class GeoHashUDF extends UDF {
private static Map<Integer,String> defaultValueMap = new HashMap<> ();
static { StringBuilder sb = new StringBuilder(""); for(int i = 0; i < 20; i++){ defaultValueMap.put(i,sb.toString()); sb.append(0); } }
public String evaluate (Double lat,Double lon,Integer precision) { try { return GeoHash.geoHashStringWithCharacterPrecision(lat, lon, precision); }catch (Exception e) { return defaultValueMap.get(precision); } }
public static void main(String[] args) { System.out.println(new GeoHashUDF().evaluate(20.1,111.2,6)); }
}
|
打jar包
先执行gradle copyToLib,再执行 gradle fatJar
得到 hiveFunction.jar
二 创建function
1 创建临时function
- 先将生成的jar包添加到hive的lib目录下
1 2
| \cp -f hiveFunction.jar $HIVE_HOME/lib/
|
- 再在hive shell里面执行以下命令即可,注意要使用全称类名
1 2
| create temporary function geohash as 'GeoHashUDF';
|
- 删除
1 2
| drop temporary function if exists geohash;
|
2 创建永久function
- 上传jar包到hdfs上
script1 2
| hadoop fs -rm /my/hive/libs/hiveFunction.jar hadoop fs -put hiveFunction.jar /my/hive/libs/hiveFunction.jar
|
- 创建永久函数
script1 2
| create function geohash as 'com.test.hive.function.GeoHashUDF' using jar 'hdfs:///my/hive/libs/hiveFunction.jar';
|
- 删除
1 2
| drop function if exists geohash;
|