hive--udf函數(開發-4種加載方式)


UDF函數開發

標准函數(UDF):以一行數據中的一列或者多列數據作為參數然后返回解雇歐式一個值的函數,同樣也可以返回一個復雜的對象,例如array,map,struct。

聚合函數(UDAF):接受從零行到多行的零個到多個列,然后返回單一值。例如sum函數。

生成函數(UDTF):接受零個或者多個輸入,然后產生多列或者多行輸出。

udf函數開發

當Hive提供的內置函數無法滿足你的業務處理需要時,此時就可以考慮使用用戶自定義函數,用戶自定義函數(user defined function),針對單條記錄。編寫一個UDF,需要繼承UDF類,並實現evaluate()函數。在查詢執行過程中,查詢中對應的每個應用到這個函數的地方都會對這個類進行實例化。對於每行輸入都會調用到evaluate()函數。而evaluate()函數處理的值會返回給Hive。同時用戶是可以重載evaluate方法的。Hive會像Java的方法重載一樣,自動選擇匹配的方法。

准備數據:

littlebigdata.txt

edward capriolo,edward@media6degrees.com,2-12-1981,209.191.139.200,M,10
bob,bob@test.net,10-10-2004,10.10.10.1,M,50
sara connor,sara@sky.net,4-5-1974,64.64.5.1,F,2

創建表:

create table if not exists littlebigdata(
name string,
email string,
bday string,
ip string,
gender string,
anum int
)
row format delimited fields terminated by ',';

加載數據:

load data local inpath 'littlebigdata.txt' into table littlebigdata;

代碼示例:

import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.junit.Test;

public class UDFZodiacSign extends UDF {
    
    private  SimpleDateFormat df ;
    
    public UDFZodiacSign() {
        df = new SimpleDateFormat("MM-dd-yyyy");
    }
    
    public  String evaluate(Date bday){
        return evaluate(bday.getMonth(),bday.getDay());
    }
    
    public  String evaluate(String bday){
        Date date =null;
        try{
            date = df.parse(bday);
        }
        catch(Exception ex){
            System.out.println("異常");
            ex.printStackTrace();
            return null;    
        }
        return evaluate(date.getMonth()+1,date.getDay());
    }
    
    public  String evaluate(Integer month,Integer day){
        if(month ==1){
            if(day<20){
                return "Capricorn";
            }else{
                return "Aquarius";
            }
        }
        if(month ==2){
            if(day<19){
                return "Capricorn";
            }else{
                return "Pisces";
            }
        }
        if(month ==3){
            if(day<20){
                return "Pisces";
            }else{
                return "Aries";
            }
        }
        if(month ==4){
            if(day<20){
                return "Aries";
            }else{
                return "Taurus";
            }
        }
        if(month ==5){
            if(day<20){
                return "Taurus";
            }else{
                return "Gemini";
            }
        }
        if(month ==6){
            if(day<21){
                return "Gemini";
            }else{
                return "Cancer";
            }
        }
        if(month ==7){
            if(day<22){
                return "Cancer";
            }else{
                return "Leo";
            }
        }
        if(month ==8){
            if(day<23){
                return "Leo";
            }else{
                return "Virgo";
            }
        }
        if(month ==9){
            if(day<22){
                return "Virgo";
            }else{
                return "Libra";
            }
        }
        if(month ==10){
            if(day<24){
                return "Libra";
            }else{
                return "Scorpio";
            }
        }
        if(month ==11){
            if(day<22){
                return "Scorpio";
            }else{
                return "Sagittarius";
            }
        }
        if(month ==12){
            if(day<22){
                return "Sagittarius";
            }else{
                return "Capricorn";
            }
        }
        
        return null;
    }
    @Test
    public void test() {
        
        UDFZodiacSign aa = new UDFZodiacSign();
        String str = aa.evaluate("01-10-2004");
        System.out.println(str);
    }

}
udf代碼示例

函數使用

加載:

add jar testUDF-0.0.1-SNAPSHOT.jar;
create temporary function zodiac as "cn.rtmap.bigdata.hive.testUDF.udf.UDFZodiacSign";

查詢:

select name,bday,zodiac(bday) from littlebigdata;

結果:

edward capriolo    2-12-1981    Capricorn
bob    10-10-2004    Libra
sara connor    4-5-1974    Aries

注意:這個地方可能有報錯,反正我是遇到了!

解決辦法:

1,修改jdk的版本 可能版本太高。
2,刪除META-INF 文件中*.SF的文件,這個是依賴包有沖突導致的。
3.在MANIFEST.MF 中添加Main-Class: cn.rtmap.bigdata.hive.testUDF.udf.UDFZodiacSign,這個可以在maven中創建好。

UDF四種加載方式

第一種:

是最常見但也不招人喜歡的方式是使用ADD JAR(s)語句,之所以說是不招人喜歡是,通過該方式添加的jar文件只存在於當前會話中,當會話關閉后不能夠繼續使用該jar文件,最常見的問題是創建了永久函數到metastore中,再次使用該函數時卻提示ClassNotFoundException。所以使用該方式每次都要使用ADD JAR(s)語句添加相關的jar文件到Classpath中。

第二種:

是修改hive-site.xml文件。修改參數hive.aux.jars.path的值指向UDF文件所在的路徑。,該參數需要手動添加到hive-site.xml文件中。
<property>
<name>hive.aux.jars.path</name>
<value>file:///jarpath/all_new1.jar,file:///jarpath/all_new2.jar</value>
</property>

 第三種:

是在${HIVE_HOME}下創建auxlib目錄,將UDF文件放到該目錄中,這樣hive在啟動時會將其中的jar文件加載到classpath中。(推薦)

 第四種:

是設置HIVE_AUX_JARS_PATH環境變量,變量的值為放置jar文件的目錄,可以拷貝${HIVE_HOME}/conf中的hive-env.sh.template為hive-env.sh文件,並修改最后一行的#export HIVE_AUX_JARS_PATH=為exportHIVE_AUX_JARS_PATH=jar文件目錄來實現,或者在系統中直接添加HIVE_AUX_JARS_PATH環境變量。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM