簡體   English   中英

帶有外部庫的Hadoop Hive UDF

[英]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下載),但是我不知道在哪里。

有什么建議么?

謝謝,米哈爾

可能是幾件事。 最好的辦法是檢查日志,但這是您可以在一分鍾內檢查的一些快速事項的列表。

  1. jar不包含所有依賴項。 我不確定eclipse如何構建可運行的jar,但是它可能不包括所有依賴項。 你可以做

    jar tf your-udf-jar.jar

看看其中包含什么。 您應該從com.decibel.uasparser看到內容。 如果不是,則必須使用適當的依賴關系來構建jar(通常使用maven來執行此操作)。

  1. 不同版本的JVM。 如果使用jdk8進行編譯,並且集群運行jdk7,則它也會失敗

  2. 蜂巢版。 有時,Hive API會稍有變化,以至於不兼容。 此處可能不是這種情況,但請確保針對集群中具有的相同版本的hadoop和hive編譯UDF

  3. 調用parse()后,您應始終檢查info是否為null

  4. 圖書館似乎使用了密鑰,這意味着實際上是從在線服務(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中,但這取決於在您的安裝上)。

這樣的問題可能可以通過以下步驟解決:

  1. 覆蓋方法UDF.getRequiredJars() ,使其返回hdfs文件路徑列表,其值取決於將以下xxx_lib文件夾放入hdfs的位置。 請注意,列表薄霧完全包含每個jar的完整hdfs路徑字符串,例如hdfs://yourcluster/some_path/xxx_lib/some.jar

  2. 導出您的udf按照“運行的JAR文件導出向導”碼(選擇“復制所需的庫到旁邊的生成JAR的子文件夾”,將導致xxx.jar,毗鄰xxx.jar lib文件夾xxx_lib此步驟

  3. 根據步驟0中的代碼將xxx.jar和文件夾xxx_lib放入您的hdfs文件系統。

  4. 使用以下命令創建udf:添加jar $ {the-xxx.jar-hdfs-path}; 創建函數your-function作為$} udf類的合格名稱};

試試吧。 我測試了它並且有效

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM