1. 程式人生 > >好程式設計師大資料學習路線分享UDF函式

好程式設計師大資料學習路線分享UDF函式

1.為什麼需要UDF?

1)、因為內部函式沒法滿足需求。

2)、hive它本身就是一個靈活框架,允許用自定義模組功能,如可以自定義UDF、serde、輸入輸出等。

2.UDF是什麼?

UDF:user difine function,使用者自定義函式,一對一。常用 udaf:user define aggregate function,使用者自定義聚合函式,多對一。 udtf:user define table_generate function,使用者自定義表生成函式,一對多。

3.怎麼編寫UDF函式??

1)、該類需要繼承UDF,重寫evaluate(),允許該方法過載。

2)、也可以繼承 generic UDF,需要重寫 initliaze() 、 getDisplay() 、 evaluate()

4.UDF的使用

第一種:(當前session有效)

package edu.qianfeng.UDF;

import org.apache.hadoop.hive.ql.exec.UDF;

/**
 * 使用Java 自定義UDF
 * @author lyd
 *
 *1603  1603_class
 */
public class FirstUDF extends UDF{
//重寫evaluate()
public String evaluate

(String str){
//判斷
if(str == null){
return null;
}
return str+"_class";
}
}

1、新增自定UDF的jar包

hive>add jar /home/h2h.jar;

2、建立臨時函式

hive>create temporary function myfunc as "edu.qianfeng.UDF.FirstUDF";

3、測試是否新增好:

show functions;
select myfunc("1603");

4、確定無用時可以刪除:

drop temporary function myfunc;

第二種:(當前session有效)

package edu.qianfeng.UDF;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.json.JSONException;
import org.json.JSONObject;

public class KeyToValue extends UDF{
public String evaluate(String str,String key){
if(str == null || key == null){
return null;
}
//sex=1&hight=180&weight=130&sal=28000
//{sex:}
String str1 = str.replace("=", ":");
String str2 = str1.replace("&", ",");
String str3 = "{"+str2+"}";
String value = "";
try {
JSONObject jo = new JSONObject(str3);
value = jo.get(key).toString();
} catch (JSONException e) {
e.printStackTrace();
}
return value;
}
public static void main(String[] args) {
System.out.println(new KeyToValue().evaluate("sex=1&hight=180&weight=130&sal=28000&facevalue=900", "facevalue"));
}
}

1、新增自定UDF的jar包(hive.aux.jars.path在該目錄下的jar會在hive啟動時自動載入)

<property>
    <name>hive.aux.jars.path</name>
    <value>$HIVE_HOME/auxlib</value>
</property>

cp /home/h2h.jar $HIVE_HOME/auxlib/

2、啟動hive,建立臨時函式

hive>create temporary function ktv as "edu.qianfeng.UDF.KeyToValue";

3、測試是否新增好:

show functions;
select myfunc("1603");

4、確定無用時可以刪除:

drop temporary function myfunc;

第三種:(當前session有效)

1、建立一個初始化檔案:

vi ./init-hive
add jar /home/h2h.jar;
create temporary function ktv1 as "edu.qianfeng.UDF.KeyToValue";

2、啟動使用命令:

hive -i ./init-hive

3、測試是否新增好:

show functions;
select myfunc("1603");

4、確定無用時可以刪除:

drop temporary function myfunc;

第四種:(做成永久性)

package edu.qianfeng.UDF;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import org.apache.hadoop.hive.ql.exec.UDF;

/**
 * 根據出生年月獲取週歲
 * @author lyd
 * 
 * 2000-04-19 17
 * 2000-04-20 16
 * 2000-04-21 16
 *
 */
public class BirthdayToAge extends UDF{
    public static void main(String[] args) {
System.out.println(new BirthdayToAge().evaluate("2000-04-20"));
}
public String evaluate(String birthday){
if(birthday == null || birthday.trim().isEmpty()){
return null;
}
String age = "";
try {
//獲取出生時間
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//獲取出生的時間戳
long bithdayts = sdf.parse(birthday).getTime();
//獲取今天的時間戳
long nowts = new Date().getTime();
//獲取從出生到現在有多少秒
long alldays = (nowts - bithdayts)/1000/60/60/24;
if(alldays < 0){
return null;
}
//判斷閏年
int birthdayyear = Integer.parseInt(birthday.split("-")[0]);
Calendar ca = Calendar.getInstance();
int nowyear = ca.get(Calendar.YEAR);
//迴圈找
int rnday = 0;
for (int i = birthdayyear; i < nowyear; i++) {
if((i%400 == 0) || (i%4 == 0 && i%100 != 0)){
rnday ++ ;
}
}
//將閏年的額天數減掉
age = (alldays-rnday)/365+"";
} catch (ParseException e) {
return null;
}
return age;
}
}

需要對原始碼編譯。 1)將寫好的Jave檔案拷貝到~/install/hive-0.8.1/src/ql/src/java/org/apache/hadoop/hive/ql/UDF/

cd  ~/install/hive-0.8.1/src/ql/src/java/org/apache/hadoop/hive/ql/UDF/
ls -lhgt |head

2)修改~/install/hive-0.8.1/src/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java,增加import和RegisterUDF

import com.meilishuo.hive.UDF.UDFIp2Long;   //新增import
registerUDF("ip2long", UDFIp2Long.class, false); //新增register

3)在~/install/hive-0.8.1/src下執行ant -Dhadoop.version=1.0.1 package

cd ~/install/hive-0.8.1/src
ant -Dhadoop.version=1.0.1 package

4)替換exec的jar包,新生成的包在/hive-0.8.1/src/build/ql目錄下,替換連結

cp hive-exec-0.8.1.jar /hadoop/hive/lib/hive-exec-0.8.1.jar.0628
rm hive-exec-0.8.1.jar
ln -s hive-exec-0.8.1.jar.0628 hive-exec-0.8.1.jar