udf開發(fā)入門(python udf、hive udf)

開發(fā)前的聲明

????? ? udf開發(fā)是在數(shù)據(jù)分析的時(shí)候如果內(nèi)置的函數(shù)解析不了的情況下去做的開發(fā),比方說(shuō)你只想拆分一個(gè)字段,拼接一個(gè)字段之類的,就不要去搞udf了,這種基本的需求自帶函數(shù)完全支持,具體參數(shù)可參考文檔:

????????http://spark.apache.org/docs/latest/api/sql/search.html?q=cast

?????? ?里面列舉了所有函數(shù)的介紹和使用,推薦優(yōu)先使用官方推出的,因?yàn)樽约簩懙膗df如果對(duì)一些異常處理不到位可能會(huì)導(dǎo)致數(shù)據(jù)分析的失敗或者意想不到的情況。但是內(nèi)置的函數(shù)真的滿足不了那就真的沒(méi)辦法了,比如在做數(shù)據(jù)分析的時(shí)候經(jīng)常使用的是ip解析,這個(gè)通常就需要自己開發(fā)udf了。

udf的分類

????? ? udf平常用的多的也就兩種,一種java寫的,一種python 所寫,下面對(duì)這兩種情況分別做個(gè)簡(jiǎn)單的demo供大家參考。

udf for java(idea)

????? ? 1.創(chuàng)建maven工程

????????? ? file->project structure->modules->點(diǎn)擊+號(hào)->new module->選擇maven

?

? ? ? ? ? ? 點(diǎn)擊next,填寫groupid(對(duì)應(yīng)包結(jié)構(gòu))、artifactid(maven倉(cāng)庫(kù)對(duì)應(yīng)的坐標(biāo))

? ? ? ? ? ??source java 代碼,操作如下圖file->project structure,

?

? ? ? ? ? ? 點(diǎn)擊apply,

? 2.開始寫java代碼

????????? ? pom文件添加依賴

org.apache.hive

hive-exec

0.13.1

?

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

public class HelloUdf? extends UDF {

public String evaluate(String ip) {

return ip+ip;

}

public int evaluate(int ip) {

return ip+ip;

}

????????????}

3.編包上傳到hdfs

????????? 在此項(xiàng)目pom文件的路徑下執(zhí)行mvn clean install

? ? ? ? ? 將target文件中生成的jar文件上傳到hdfs上,路徑自己自定義,我直接上傳到/。

? ? ? ? ??sudo -u hdfs hdfs dfs -put testudf-1.0-SNAPSHOT.jar /

? ? ? 4.使用hivesql或者sparksql加載自定義函數(shù)

????????? ?beeline -u jdbc:hive2://node113.leap.com:10000 -n hive

? ? ? ? ? ?create function test.iptonum as 'com.liubl.HelloUdf' using jar 'hdfs:///testudf-1.0-SNAPSHOT.jar';

? ? ? ? ? ?(com.liubl.HelloUdf為代碼類的全路徑自己去粘貼一下)

? ? ? ? ? ?(測(cè)試sql見(jiàn)圖)

?

udf for python

????? ? python udf入門我就不重新闡述了,我看到有一位同學(xué)的博客寫的很清晰,推薦博客

? ? ? ? https://blog.csdn.net/qq_26937525/article/details/54136317

? ? ? ? 存在的問(wèn)題:? ?

在數(shù)據(jù)清洗過(guò)程中,如果使用的是TransForm而不是UDF的話,因?yàn)镻ython是直接向系統(tǒng)申請(qǐng)資源的,而不是像ResourceManager申請(qǐng)資源,故會(huì)導(dǎo)致啟動(dòng)的Python腳本對(duì)內(nèi)存和CPU的使用不可控,尤其是當(dāng)啟動(dòng)多個(gè)Map時(shí),因?yàn)橐粋€(gè)map將啟動(dòng)一個(gè)Python因此,當(dāng)同時(shí)運(yùn)行的map有幾十個(gè)時(shí)(測(cè)試集群較?。?,同時(shí)將嘗試啟動(dòng)相同個(gè)數(shù)的python(資源夠用的話仍然會(huì)啟動(dòng)幾十個(gè)),且此時(shí)Map占用的內(nèi)存是不會(huì)釋放掉的他在一直等待Python的結(jié)果,這將導(dǎo)致python可用的資源僅僅是原本分配給系統(tǒng)的很少的資源(注:在安裝Hadoop時(shí),對(duì)于單個(gè)節(jié)點(diǎn),一般僅僅給系統(tǒng)留出很少的內(nèi)存,其他的內(nèi)存全部分給了集群。例如32G物理內(nèi)存的節(jié)點(diǎn)給系統(tǒng)和dataNode+nodeManager的內(nèi)存就4-8個(gè)G,同時(shí)CPU核數(shù)也不足節(jié)點(diǎn)的一半,剩余的內(nèi)存和cpu核數(shù)全部劃分給集群使用。需要注意的是,這里雖然說(shuō)是劃分給集群使用,僅僅是邏輯上的劃分,即規(guī)定集群可以使用的最大的物理內(nèi)存,超過(guò)該內(nèi)存時(shí)MR可以認(rèn)為是不會(huì)搶占分配給系統(tǒng)+DataNode+nodeManager的內(nèi)存的,但是當(dāng)集群中沒(méi)有MR在執(zhí)行,即沒(méi)有map或者reduce在執(zhí)行時(shí),劃分給集群的這部分資源是可以被系統(tǒng)使用的。而若有map和Reduce在執(zhí)行時(shí),運(yùn)行map和reduce的JVM的資源不會(huì)因?yàn)橄到y(tǒng)進(jìn)程需要使用而被釋放掉)所以,所有正在執(zhí)行的Map一直在等待python的運(yùn)行結(jié)果而沒(méi)有釋放掉其自身占用的資源,故python無(wú)法使用分配給集群的資源而只能使用預(yù)留給系統(tǒng)+nodeManager+DataNode的4-8G的內(nèi)存和很少的cpu核數(shù)。因此會(huì)導(dǎo)致集群的資源無(wú)法被高效利用。

綜上,使用Transform(Python)執(zhí)行效率低的根本原因在于Python是直接向操作系統(tǒng)申請(qǐng)資源,而不是向YARN的ResourceManager申請(qǐng)資源,故而導(dǎo)致節(jié)點(diǎn)的資源無(wú)法高效組織和被利用。此外,不要輕易使用transform!不要輕易使用transform!不要輕易使用transform

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容