Hadoop Hive UDF与外部库

问题描述 投票:1回答:2

我正在尝试为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();
    }
}

我想到的事实应该提到:

  • 我正在使用Eclipse编译“export runnable jar file”并将所需的库提取到生成的jar选项中
  • 我正在用Hue上传这个“胖罐”文件
  • 我设法运行的最低工作示例: public String evaluate(String i) { return "hello" + i.toString()"; }
  • 我想问题就在那个库附近(从https://udger.com下载)我正在使用,但我不知道在哪里。

有什么建议?

谢谢,米哈尔

java hadoop hive user-agent udf
2个回答
1
投票

这可能是一些事情。最好的办法是检查日志,但这里列出了一些你可以在一分钟内查看的快速内容。

  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. 在调用info之后,您应该始终检查parse()是否为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; 
    }
}

但要确切地知道,你必须查看日志......纱线日志,还可以查看你正在提交作业的机器上的hive日志(可能在/ var / log / hive中,但它取决于在你的安装上)。


0
投票

这样的问题可能可以通过以下步骤解决:

  1. UDF.getRequiredJars()方法之上,让它返回一个hdfs文件路径列表,其中的值由您将以下xxx_lib文件夹放入hdfs的位置确定。请注意,列表雾完全包含每个jar的完整hdfs路径字符串,例如hdfs://yourcluster/some_path/xxx_lib/some.jar
  2. 按照“Runnable jar文件导出向导”导出你的udf代码(选择“将所需的库复制到生成的jar旁边的子文件夹中”。这些步骤将导致xxx.jar和xxx.jar旁边的lib文件夹xxx_lib
  3. 根据您在步骤0中的代码将xxx.jar和文件夹xxx_lib放到您的hdfs文件系统中。
  4. 使用以下命令创建一个udf:add jar $ {the-xxx.jar-hdfs-path};创建函数your-function为$} udf class的限定名};

试试吧。我测试这个,它的工作原理

© www.soinside.com 2019 - 2024. All rights reserved.