spark sql 1.5.0 也支持

Spark(Hive) SQL中UDF的使用

相对于使用MapReduce或者Spark Application的方式进行数据分析,使用Hive SQL或Spark SQL能为我们省去不少的代码工作量,而Hive SQL或Spark SQL本身内置的各类UDF也为我们的数据处理提供了不少便利的工具,当这些内置的UDF不能满足于我们的需要时,Hive SQL或Spark SQL还为我们提供了自定义UDF的相关接口,方便我们根据自己的需求进行扩展。
在Hive的世界里使用自定义UDF的过程是比较复杂的。我们需要根据需求使用Java语言开发相应的UDF(UDAF、UDTF),然后将UDF的代码及其依赖编译打包为Jar,使用方法有两种:
(1)临时函数
在一次会话(Session)中使用如下语句创建临时函数:


add jar /usr/local/fqlhadoop/spark/lib/hive_udf.jar 
 create temporary function row_sequence as 'org.rowsequence.RowSequence'; 
 select id,row_sequence() from test.test limit 2;


这种方式有一个缺点:每一次会话过程中使用函数时都需要创建,而且仅在当前会话中有效。
(2)永久函数
这个特性需要高版本的Hive支持,它的好处是可以将UDF Jar存放至HDFS,函数仅需要创建一次即可以永久使用,如下:
(需要将hive_udf.jar(每台spark服务器)添加到spark_env.sh 中的spark_classpath)


CREATE FUNCTION row_sequence AS 'org.rowsequence.RowSequence' USING JAR 'hdfs://hacluster/system/hive_udf/hive_udf.jar'; 
 select id,row_sequence() from test.test limit 2;


虽然永久函数相对于临时函数有一定优势,但Java语言的开发门槛很大程度上妨碍了UDF在实际数据分析过程中使用,毕竟我们的数据分析师多数是以Python、SQL为主要分析工具的,每一次UDF的开发都需要工程师的参与,开发效率与应用效果都是不是很好(可能需要频繁更新UDF的问题),PySpark的出现确很好地解决了这个问题:它可以非常方便地将一个普通的Python函数注册为一个UDF。

(3)永久函数 推荐

 1,添加函数文件$HIVE_HOME/src/ql/src/java/org/apache/hadoop/hive/ql/udf/UrlDecode.java


package org.apache.hadoop.hive.ql.udf; 
import java.io.UnsupportedEncodingException; 
import java.net.URLDecoder; 
import org.apache.hadoop.hive.ql.exec.Description; 
import org.apache.hadoop.hive.ql.exec.UDF; 
import org.apache.hadoop.hive.ql.udf.UDFType; 
/** 
* UDUrlDecode. 
* @param <StringWritable> 
*/ 
@Description(name = "url_decode", value = "FUNC() - Returns Parsing the url string") 
@UDFType(deterministic = false) 
public class UrlDecode extends UDF{ 
private String resultUrl; 
public UrlDecode() { 

} 
public String evaluate(String url) { 
if(url!=null&&url.length()>0){ 
try { 
resultUrl =URLDecoder.decode(URLDecoder.decode(url.toString(), "utf-8"), "utf-8"); 
} catch (UnsupportedEncodingException e) { 
e.printStackTrace(); 
} 
} 
return resultUrl; 
} 
}


将编译好的class文件放入spark-assembly-1.6.0-hadoop2.6.0.jar中(必须要放)


 2.将函数UrlDecode注册到hive的函数列表中 修改$HIVE_HOME/src/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java文件 

import org.apache.hadoop.hive.ql.udf.UrlDecode;
system.registerUDF("url_decode", UrlDecode.class, true);


将编译好的class文件替换spark-assembly-1.6.0-hadoop2.6.0.jar中(必须要放)

 

url_decode
 hive> select id,url_decode('%25E9%2598%25BF%25E8%25BF%25AA%25E8%25BE%25BE%25E6%2596%25AF') from test.test;