分享

一定要解决这个UDF函数问题

cowboy2014 发表于 2015-12-10 22:07:52 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 5 35354
我写了一个UDF函数,用来读取一个配置文件Conf_Term_prds的中的正则表达式,用来匹配hive表中满足记录的数据,不满足的查询结果返回-1。
遇到的问题是:在本地Exlipse都测试完成了,但是上传到服务器执行的时候报错了。我把代码贴出来,希望大家看看!
[mw_shl_code=java,true]package com.hdfs.produce;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
public class FTermMatch extends UDF {
       
        //UDF指定调用方法
        public Text evaluate(Text input) throws UnsupportedEncodingException {
                BufferedReader in = null;
                String termType = "";
                try {
                        //File file = new File("/home/tddata/lijx/conf/Conf_Term_prds");                                                        //上线路径
                        File file = new File("E:\\精确营销\\01-任务管理\\搜索与购机分析\\01-脚本开发\\Conf_Term_prds");
                        in = new BufferedReader(new InputStreamReader(new FileInputStream(file),"UTF-8"));
                } catch (FileNotFoundException e) {
                        e.printStackTrace();
                }
                boolean ifmatch = false;
                try {
                        termType = in.readLine();
                        while(termType !=null){
                                Pattern p = Pattern.compile(termType);
                            Matcher m = p.matcher(input.toString().toLowerCase());
                                ifmatch = m.matches();         //input.toString().matches(".*荣耀.*");//
                                //System.out.println(termType+"    "+ifmatch);

                                if (ifmatch){
                                        System.out.println(clear(termType));
                                        break;
                                }else {
                                        System.out.println("匹配失败,查询下一条");
                                       
                                        termType = in.readLine();
                                        if (termType == null) {
                                                System.out.println("配置表读取完毕");
                                                termType = "-1";
                                                break;
                                        }
                                }
                        }
                } catch (IOException e) {
                        e.printStackTrace();
                }
                System.out.println(termType);
                return new Text(clear(termType));
        }
       
        public String clear(String str){
                return str.replace("[\\s]", "").replace("*", "").replace(".", "");
               
        }
       
        public static void main(String args[]) throws UnsupportedEncodingException{
                //测试用,上线请删除这个方法
                Text input = new Text("esgsdg");
                FTermMatch f = new FTermMatch();
                f.evaluate(input);
        }
       
}[/mw_shl_code]

2、Conf_Term_prds中的正则表达式我提供一些:
.*荣耀[\s]*4[\s]*x.*
.*荣耀[\s]*6.*
.*荣耀[\s]*x[\s]*1.*
.*荣耀[\s]*3[\s]*x.*
.*荣耀[\s]*3[\s]*c.*
.*g[\s]*7[\s]*华为.*
.*c[\s]*199[\s]*华为.*


3、查询过程为:
SELECT FTermMatch('我要买荣耀6了') FROM DUAL;

4、报错日志为:
[mw_shl_code=shell,true]hive (default)> SELECT FTermMatch('我要买荣耀6了') FROM DUAL;
匹配失败,查询下一条
荣耀6
Total jobs = 1
Launching Job 1 out of 1
Number of reduce tasks is set to 0 since there's no reduce operator
Starting Job = job_1449752569669_0003, Tracking URL = http://master:8088/proxy/application_1449752569669_0003/
Kill Command = /home/hadoop/hadoop-2.5.1/bin/hadoop job  -kill job_1449752569669_0003
Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 0
2015-12-10 05:44:03,008 Stage-1 map = 0%,  reduce = 0%
2015-12-10 05:44:39,503 Stage-1 map = 100%,  reduce = 0%
Ended Job = job_1449752569669_0003 with errors
Error during job, obtaining debugging information...
Examining task ID: task_1449752569669_0003_m_000000 (and more) from job job_1449752569669_0003

Task with the most failures(4):
-----
Task ID:
  task_1449752569669_0003_m_000000

URL:
  http://master:8088/taskdetails.jsp?jobid=job_1449752569669_0003&tipid=task_1449752569669_0003_m_000000
-----
Diagnostic Messages for this Task:
Error: java.lang.RuntimeException: Error in configuring object
        at org.apache.hadoop.util.ReflectionUtils.setJobConf(ReflectionUtils.java:109)
        at org.apache.hadoop.util.ReflectionUtils.setConf(ReflectionUtils.java:75)
        at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:133)
        at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:426)
        at org.apache.hadoop.mapred.MapTask.run(MapTask.java:342)
        at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:168)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Subject.java:415)
        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1614)
        at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:163)
Caused by: java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.apache.hadoop.util.ReflectionUtils.setJobConf(ReflectionUtils.java:106)
        ... 9 more
Caused by: java.lang.RuntimeException: Error in configuring object
        at org.apache.hadoop.util.ReflectionUtils.setJobConf(ReflectionUtils.java:109)
        at org.apache.hadoop.util.ReflectionUtils.setConf(ReflectionUtils.java:75)
        at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:133)
        at org.apache.hadoop.mapred.MapRunner.configure(MapRunner.java:38)
        ... 14 more
Caused by: java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.apache.hadoop.util.ReflectionUtils.setJobConf(ReflectionUtils.java:106)
        ... 17 more
Caused by: java.lang.RuntimeException: Map operator initialization failed
        at org.apache.hadoop.hive.ql.exec.mr.ExecMapper.configure(ExecMapper.java:154)
        ... 22 more
Caused by: org.apache.hadoop.hive.ql.exec.UDFArgumentException: org.apache.hadoop.hive.ql.metadata.HiveException: Unable to execute method public org.apache.hadoop.io.Text com.hdfs.produce.FTermMatch.evaluate(org.apache.hadoop.io.Text) throws java.io.UnsupportedEncodingException  on object com.hdfs.produce.FTermMatch@632deed0 of class com.hdfs.produce.FTermMatch with arguments {我要买荣耀6了:org.apache.hadoop.io.Text} of size 1
        at org.apache.hadoop.hive.ql.udf.generic.GenericUDF.initializeAndFoldConstants(GenericUDF.java:148)
        at org.apache.hadoop.hive.ql.exec.ExprNodeGenericFuncEvaluator.initialize(ExprNodeGenericFuncEvaluator.java:127)
        at org.apache.hadoop.hive.ql.exec.Operator.initEvaluators(Operator.java:931)
        at org.apache.hadoop.hive.ql.exec.Operator.initEvaluatorsAndReturnStruct(Operator.java:957)
        at org.apache.hadoop.hive.ql.exec.SelectOperator.initializeOp(SelectOperator.java:65)
        at org.apache.hadoop.hive.ql.exec.Operator.initialize(Operator.java:376)
        at org.apache.hadoop.hive.ql.exec.Operator.initialize(Operator.java:460)
        at org.apache.hadoop.hive.ql.exec.Operator.initializeChildren(Operator.java:416)
        at org.apache.hadoop.hive.ql.exec.TableScanOperator.initializeOp(TableScanOperator.java:189)
        at org.apache.hadoop.hive.ql.exec.Operator.initialize(Operator.java:376)
        at org.apache.hadoop.hive.ql.exec.MapOperator.initializeOp(MapOperator.java:425)
        at org.apache.hadoop.hive.ql.exec.Operator.initialize(Operator.java:376)
        at org.apache.hadoop.hive.ql.exec.mr.ExecMapper.configure(ExecMapper.java:133)
        ... 22 more
Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: Unable to execute method public org.apache.hadoop.io.Text com.hdfs.produce.FTermMatch.evaluate(org.apache.hadoop.io.Text) throws java.io.UnsupportedEncodingException  on object com.hdfs.produce.FTermMatch@632deed0 of class com.hdfs.produce.FTermMatch with arguments {我要买荣耀6了:org.apache.hadoop.io.Text} of size 1
        at org.apache.hadoop.hive.ql.exec.FunctionRegistry.invoke(FunctionRegistry.java:1243)
        at org.apache.hadoop.hive.ql.udf.generic.GenericUDFBridge.evaluate(GenericUDFBridge.java:182)
        at org.apache.hadoop.hive.ql.udf.generic.GenericUDF.initializeAndFoldConstants(GenericUDF.java:145)
        ... 34 more
Caused by: java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.apache.hadoop.hive.ql.exec.FunctionRegistry.invoke(FunctionRegistry.java:1219)
        ... 36 more
Caused by: java.lang.NullPointerException
        at com.hdfs.produce.FTermMatch.evaluate(FTermMatch.java:30)
        ... 41 more


FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask
MapReduce Jobs Launched:
Job 0: Map: 1   HDFS Read: 0 HDFS Write: 0 FAIL
Total MapReduce CPU Time Spent: 0 msec[/mw_shl_code]

已有(5)人评论

跳转到指定楼层
atsky123 发表于 2015-12-11 10:56:39
楼主尝试下面两个办法来进行排除:

1.可能是编码问题,楼主测试下英文字符。
2.楼主直接使用的Java数据类型,尝试转换成hadoop数据类型

回复

使用道具 举报

cranberries8 发表于 2015-12-11 12:14:20
本帖最后由 cranberries8 于 2015-12-11 12:29 编辑

你的异常显示的是 java.lang.NullPointerException   :at com.hdfs.produce.FTermMatch.evaluate(FTermMatch.java:30)
先照这个思路下:
就是你的文件流 in 没有初始化成功!
由于异常信息没看完整,但是出现这个错误还不抛异常往下走也就是异常被捕获咯但没处理:
应该是 FileNotFoundException
也就是你的  
File file = new File("E:\\精确营销\\01-任务管理\\搜索与购机分析\\01-脚本开发\\Conf_Term_prds");
你的文件怎么还有E盘???

回复

使用道具 举报

cowboy2014 发表于 2015-12-11 12:53:51
cranberries8 发表于 2015-12-11 12:14
你的异常显示的是 java.lang.NullPointerException   :at com.hdfs.produce.FTermMatch.evaluate(FTermMat ...

谢谢!这个是在windows下测试的环境。正式的环境是配在前面注释掉的那一段的。
问题查出来了,确实是这个原因。只是在一个节点上上传了配置文件,其他的节点没有同步吧,也就是报错信息是来自于其他节点。我对in加一个非空判断,这个问题确实就解决掉了,但是实际上任务还是在单节点执行的(对吗?我的猜测)。现在应该想想怎么把配置文件也同步到其他的节点。
请问使用hive>add file /home/tddata/lijx/conf/Conf_Term_prds;可以达到这个效果吗?
回复

使用道具 举报

cranberries8 发表于 2015-12-11 13:01:54
本帖最后由 cranberries8 于 2015-12-11 13:04 编辑
cowboy2014 发表于 2015-12-11 12:53
谢谢!这个是在windows下测试的环境。正式的环境是配在前面注释掉的那一段的。
问题查出来了,确实是这 ...

,你可以考虑吧配置文件放在hdfs上面 。或者利用hdfs DistributedCache ,你可以试试 add file 那种方式 ,我没用过配置文件的方式,所以不能肯定
如果是可以的话估计也是利用的 DistributedCache 这种方式
回复

使用道具 举报

cowboy2014 发表于 2015-12-24 13:35:06
cranberries8 发表于 2015-12-11 13:01
,你可以考虑吧配置文件放在hdfs上面 。或者利用hdfs DistributedCache ,你可以试试 add file 那种方式  ...

现在偶尔还是会出现找不到配置文件的报错:
问题解决方式总结为:
1、把配置文件上传到的HDFS,然后add file的时候引用hdfs的路径;
2、在java代码中,对外部文件的调用方式为,设置String path = "./{your file name}";

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条