Hadoop 在配置单元中执行自定义UDF

Hadoop 在配置单元中执行自定义UDF,hadoop,mapreduce,hive,Hadoop,Mapreduce,Hive,我的蜂箱里有下表 >describe weblogs; OK originatingip string clientidentity string userid string time

我的蜂箱里有下表

>describe weblogs;
OK
originatingip           string                                      
clientidentity          string                                      
userid                  string                                      
time                    string                                      
requesttype             string                                      
requestpage             string                                      
httpprotocolversion     string                                      
responsecode            int                                         
responsesize            int                                         
referrer                string                                      
useragent               string                                      
Time taken: 1.065 seconds, Fetched: 11 row(s)
我已经用Java创建了一个UDF来映射Ip地址和地理位置。以下是我的UDF

package com.prithvi.hive.logprocessing.udf.ipgeo;
public class IpgeoHive extends UDF {

Text result = new Text();
String ipCountry, ipCity;

public Text evaluate(Text input) throws IOException {
    if(input==null)return null;
    URL database_path = getClass().getResource("/GeoLiteCity.dat");
    File file;
    try {
      file = new File(database_path.toURI());
    } catch(URISyntaxException e) {
      file = new File(database_path.getPath());
    }
    LookupService cl = new LookupService(file);
    Location location = cl.getLocation(input.toString());
    if (location != null) {
        ipCountry = location.countryName;
        ipCity = location.city;
    } else {
        ipCountry = "Unknown";
        ipCity = "Unknown";
    }
    result.set(ipCountry+"/"+ipCity);
    return result;
}
}
当通过在eclipse中传递伪值进行测试时,上述udf返回的结果与预期一致

构建jar文件后,我使用以下命令在沙箱中运行它

ADD JAR MapReduce_Examples-0.0.1-SNAPSHOT-jar-with-dependencies.jar;

CREATE TEMPORARY FUNCTION IP2GEO AS 'com.prithvi.hive.logprocessing.udf.ipgeo.IpgeoHive';

SELECT originatingip, IP2GEO(originatingip) from weblogs limit 10;
但作业失败,出现以下错误,我不知道如何解决此问题。非常感谢您的帮助。

此任务的诊断消息: 错误:java.lang.RuntimeException:org.apache.hadoop.hive.ql.metadata.HiveException:hive运行时在处理行{“originatingip”:“25.198.250.35”、“clientidentity”:“-”、“userid”:“,”time:“[2014-07-19T16:05:33Z]”、“requesttype”:“GET”,“requestpage”:“/”、“httpprotocolversion”:“HTTP/1.1\”、“responsecode”:404、“responsesize”:1081,“引用者”:“\”-\”,“用户代理”:“\”Mozilla/4.0(兼容;MSIE 6.0;Windows NT 5.1;SV1;.NET CLR 1.1.4322)\“” 位于org.apache.hadoop.hive.ql.exec.mr.ExecMapper.map(ExecMapper.java:195) 位于org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:54) 位于org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:430) 位于org.apache.hadoop.mapred.MapTask.run(MapTask.java:342) 位于org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:167) 位于java.security.AccessController.doPrivileged(本机方法) 位于javax.security.auth.Subject.doAs(Subject.java:415) 位于org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1557) 位于org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:162) 原因:org.apache.hadoop.hive.ql.metadata.HiveException:处理行{“originatingip”:“25.198.250.35”、“clientidentity”:“,“userid”:“,”时间“:”[2014-07-19T16:05:33Z],“requesttype”:“GET”,“requestpage”:“,“httpprotocolversion”:“HTTP/1.1\”,“responsecode”:404,“responsesize”:1081,“referrer”:“,”useragent:“:”\“Mozilla/4.0(兼容;MSIE 6.0;Windows NT 5.1;SV1;.NET CLR 1.1.4322)\”“” 位于org.apache.hadoop.hive.ql.exec.MapOperator.process(MapOperator.java:550) 位于org.apache.hadoop.hive.ql.exec.mr.ExecMapper.map(ExecMapper.java:177) ... 8个以上 原因:org.apache.hadoop.hive.ql.metadata.HiveException:无法执行方法public org.apache.hadoop.io.Text com.prithvi.hive.logprocessing.udf.ipgeo.IpgeoHive.evaluate(org.apache.hadoop.io.Text)在对象com.prithvi.hive.logprocessing.udf.ipgeo上引发java.io.IOException。IpgeoHive@63c0b9c3具有大小为1的参数{25.198.250.35:org.apache.hadoop.io.Text}的com.prithvi.hive.logprocessing.udf.ipgeo.IpgeoHive类 位于org.apache.hadoop.hive.ql.exec.FunctionRegistry.invoke(FunctionRegistry.java:1241) 位于org.apache.hadoop.hive.ql.udf.generic.GenericUDFBridge.evaluate(GenericUDFBridge.java:182) 位于org.apache.hadoop.hive.ql.exec.exprnodegenericfuncealuator.\u evaluate(exprnodegenericfuncealuator.java:166) 位于org.apache.hadoop.hive.ql.exec.ExprNodeEvaluator.evaluate(ExprNodeEvaluator.java:77) 位于org.apache.hadoop.hive.ql.exec.ExprNodeEvaluator.evaluate(ExprNodeEvaluator.java:65) 位于org.apache.hadoop.hive.ql.exec.SelectOperator.processOp(SelectOperator.java:79) 位于org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:793) 位于org.apache.hadoop.hive.ql.exec.TableScanOperator.processOp(TableScanOperator.java:92) 位于org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:793) 位于org.apache.hadoop.hive.ql.exec.MapOperator.process(MapOperator.java:540) ... 9更多 原因:java.lang.reflect.InvocationTargetException 在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处 在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)中 在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中 位于java.lang.reflect.Method.invoke(Method.java:606) 位于org.apache.hadoop.hive.ql.exec.FunctionRegistry.invoke(FunctionRegistry.java:1217) ... 还有18个 原因:java.lang.IllegalArgumentException:URI不是分层的 在java.io.File.(File.java:418) 位于com.prithvi.hive.logprocessing.udf.ipgeo.IpgeoHive.evaluate(IpgeoHive.java:28) ... 23多 失败:执行错误,从org.apache.hadoop.hive.ql.exec.mr.MapRedTask返回代码2 推出MapReduce作业: 作业0:映射:1 HDFS读取:0 HDFS写入:0失败 花费的MapReduce CPU总时间:0毫秒*
错误表明hive不知道java字符串/文本

您必须将java字符串/文本转换为配置单元字符串

使用下面的代码

private JavaStringObjectInspector stringInspector;
stringInspector = PrimitiveObjectInspectorFactory.javaStringObjectInspector;
String ip = stringInspector.getPrimitiveJavaObject(input);  

请将weblogs表中的示例记录添加到您的问题中。谢谢您使用的是哪一个geoip库?我仍然收到相同的错误:失败,异常为java.io.IOException:org.apache.hadoop.hive.ql.metadata.HiveException:无法执行方法公共建议最受欢迎。。及@Omkar@Prithvi514你用其他方法解决了吗??
private JavaStringObjectInspector stringInspector;
stringInspector = PrimitiveObjectInspectorFactory.javaStringObjectInspector;
String ip = stringInspector.getPrimitiveJavaObject(input);