[英]Hadoop Hive UDF with external library
我正在嘗試為Hadoop Hive編寫UDF,以解析用戶代理。 以下代碼在我的本地計算機上運行良好,但是在Hadoop上,我得到了:
org.apache.hadoop.hive.ql.metadata.HiveException:無法執行方法public java.lang.String MyUDF .evaluate(java.lang.String)對對象拋出org.apache.hadoop.hive.ql.metadata.HiveException MyUDF類的MyUDF @ 64ca8bfb,其參數為{All Occupations:java.lang.String},大小為1',
碼:
import java.io.IOException;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.*;
import com.decibel.uasparser.OnlineUpdater;
import com.decibel.uasparser.UASparser;
import com.decibel.uasparser.UserAgentInfo;
public class MyUDF extends UDF {
public String evaluate(String i) {
UASparser parser = null;
parser = new UASparser();
String key = "";
OnlineUpdater update = new OnlineUpdater(parser, key);
UserAgentInfo info = null;
info = parser.parse(i);
return info.getDeviceType();
}
}
我想到的事實是:
我正在使用帶有“導出可運行的jar文件”的Eclipse進行編譯,並將所需的庫提取到生成的jar選項中
我正在用Hue上傳此“胖罐”文件
我設法運行的最小工作示例:
public String evaluate(String i) { return "hello" + i.toString()"; }
我猜問題出在我正在使用的那個庫的某個地方(從https://udger.com下載),但是我不知道在哪里。
有什么建議么?
謝謝,米哈爾
可能是幾件事。 最好的辦法是檢查日志,但這是您可以在一分鍾內檢查的一些快速事項的列表。
jar不包含所有依賴項。 我不確定eclipse如何構建可運行的jar,但是它可能不包括所有依賴項。 你可以做
jar tf your-udf-jar.jar
看看其中包含什么。 您應該從com.decibel.uasparser
看到內容。 如果不是,則必須使用適當的依賴關系來構建jar(通常使用maven來執行此操作)。
不同版本的JVM。 如果使用jdk8進行編譯,並且集群運行jdk7,則它也會失敗
蜂巢版。 有時,Hive API會稍有變化,以至於不兼容。 此處可能不是這種情況,但請確保針對集群中具有的相同版本的hadoop和hive編譯UDF
調用parse()
后,您應始終檢查info
是否為null
圖書館似乎使用了密鑰,這意味着實際上是從在線服務(udger.com)獲取數據,因此如果沒有實際的密鑰,它可能無法工作。 更重要的是,圖書館會在線更新,並為每條記錄聯系在線服務。 這意味着,看着代碼,它將為每個記錄創建一個更新線程 。 您應該更改代碼,使其僅在構造函數中執行一次,如下所示:
更改方法如下:
public class MyUDF extends UDF {
UASparser parser = new UASparser();
public MyUDF() {
super()
String key = "PUT YOUR KEY HERE";
// update only once, when the UDF is instantiated
OnlineUpdater update = new OnlineUpdater(parser, key);
}
public String evaluate(String i) {
UserAgentInfo info = parser.parse(i);
if(info!=null) return info.getDeviceType();
// you want it to return null if it's unparseable
// otherwise one bad record will stop your processing
// with an exception
else return null;
}
}
但是要確定,您必須查看日志...紗線日志,還可以查看提交作業的機器上的配置單元日志(可能在/ var / log / hive中,但這取決於在您的安裝上)。
這樣的問題可能可以通過以下步驟解決:
覆蓋方法UDF.getRequiredJars()
,使其返回hdfs
文件路徑列表,其值取決於將以下xxx_lib文件夾放入hdfs的位置。 請注意,列表薄霧完全包含每個jar的完整hdfs路徑字符串,例如hdfs://yourcluster/some_path/xxx_lib/some.jar
導出您的udf
按照“運行的JAR文件導出向導”碼(選擇“復制所需的庫到旁邊的生成JAR的子文件夾”,將導致xxx.jar,毗鄰xxx.jar lib文件夾xxx_lib此步驟
根據步驟0中的代碼將xxx.jar和文件夾xxx_lib放入您的hdfs文件系統。
使用以下命令創建udf:添加jar $ {the-xxx.jar-hdfs-path}; 創建函數your-function作為$} udf類的合格名稱};
試試吧。 我測試了它並且有效
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.