Java 带有外部库的Hadoop Hive UDF
我正在尝试为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.HiveExceptionMyUDF@64ca8bfbMyUDF类的{All Occupations:java.lang.String}参数大小为1' 代码: 我想到的事实应该提到:Java 带有外部库的Hadoop Hive UDF,java,hadoop,hive,user-agent,udf,Java,Hadoop,Hive,User Agent,Udf,我正在尝试为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.HiveExceptionMyUDF@64ca8bfbMyUDF类
- 我使用Eclipse编译“导出可运行的jar文件”,并将所需的库提取到生成的jar选项中
- 我正在上传这个带有色调的“胖罐子”文件
- 我设法运行的最低工作示例:
公共字符串求值(字符串i){ 返回“hello”+i.toString()”; }
- 我猜问题出在我正在使用的库(下载自)的某个地方,但我不知道在哪里
谢谢,Michal,可能会有一些事情。最好的办法是检查日志,但这里列出了一些你可以在一分钟内快速检查的事情
com.decibel.uasparser
中的内容。如果没有,您必须使用适当的依赖项构建jar(通常使用maven)
parse()
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
代码。此步骤将生成xxx.jar和xxx.jar旁边的lib文件夹xxx_lib试试看。我测试了一下,它就可以工作了。你是否查看了
应用程序_xxxx_xxxx
(如Hive所报告的)的纱线日志,以检查一些线索,例如,使用比Hive使用的JRE更新的Java版本编译的JAR的一些内部异常(只是一个示例)?我们的Hadoop机器已经停机一段时间了,所以我没有机会查看日志,但是我检查了依赖项,它们似乎没有问题2)这是一个问题,是一个退步。但是,当版本不兼容时,Java会抛出一个关于错误版本的异常,而不是IOException/HiveException 3)应该可以4)我会试试这个5)它可以使用密钥(我在Hadoop外部检查).我知道效率不高,但我认为解决这个问题应该是下一步。然而,当我在图书馆里浏览时,我想到了另一个想法…它试图写入临时文件,这是UDF功能的合法操作吗(写入文件系统?HDFS是仅附加的系统,因此我在这里发现了一些问题?…谢谢,我感谢您的帮助:)UDF读取/写入本地文件是合法的,但绝对不建议这样做!但在某些情况下可以安全地完成。在以前的工作中,我们将配置文件推送到所有机器上,并使用UDF读取配置文件并将其内容提供给查询。但该库为每个记录打开网络连接。这非常有用效率高而且不好……所以是的,它闻起来有麻烦:)该库不是为hadoop设计的。在编写使用库的UDF时,您应该非常小心,看看它在内部是如何工作的。因此我发现该库还支持从文件导入该配置。但是我仍然收到“未找到文件”异常,所以我的问题是,如何找到文件的路径ded?我通过Hue上传了它,和.jar文件在同一个目录下。
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;
}
}