自定义UDF函数应用异常

本文详细记录了在Hive中使用自定义UDF函数时遇到的异常情况,包括数据库连接异常和JVM版本不兼容问题。解决方法包括:更新数据库权限设置,调整JDBC URL以匹配数据库IP,以及复制数据库驱动到YARN目录。通过这些步骤,成功解决了执行自定义函数时的错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



定义函数PlatformConvert

实现传入hive表中string类型字段,通过查询中间表,返回int类型主键id

publicclass PlatformConvert extends UDF{

    public IntWritable evaluate(Text s) throws Exception{

       if(s==null){

           returnnull;

       }

       PlatformDimension platformDimension = new PlatformDimension(s.toString());

       IDimensionConverter convert = new DimensionConverterImpl();

       intid=0;

       id = convert.getDimensionIdByValue(platformDimension);

       return  new IntWritable(id);

    }

}

 

UDF函数功能:例如参数为all,返回值为1;参数为website,返回值为2.

 

将定义好的UDF函数上传到虚拟机,并创建函数名称为p_con的临时函数

add jar /root/data/Fun.jar;

create temporary function p_con as  'myudf.DateConvert';

 

创建stats_view_depth_tmp

 

查询表stats_view_depth_tmp,并将pl字段值转化成中间表对应的id

报错内容大致意思为:不能执行自定义的函数

出现以上错误可能的情况

1.     jar不包含所有依赖项。可能不包括所有的依赖关系导致不能加载对应依赖的类信息。

2.     JVM版本不同导致。如果使用jdk8进行编译,并且集群运行jdk7,那么它也将失败

3.     蜂巢版本。有时候,蜂巢API变化很小,足够不兼容。可能不是这种情况,但是确保集群中拥有相同版本的hadoop和hive来编译UDF

4.     info调用后应该始终检查是否为空parse()

 

具体错误信息还需将进一步查看日志,只列出了关键信息

2017-07-23 19:20:15,558 ERROR [main]: impl.DimensionConverterImpl (DimensionConverterImpl.java:getDimensionIdByValue(71)) - 操作数据库出现异常

java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)

                  at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1094)

2017-07-23 19:20:15,561 ERROR [main]: CliDriver (SessionState.java:printError(960)) - Failed with exception java.io.IOException:org.apache.hadoop.hive.ql.metadata.HiveException: Unable to execute method public org.apache.hadoop.io.IntWritable UDF.PlatformConvert.evaluate(org.apache.hadoop.io.Text) throws java.lang.Exception  on object UDF.PlatformConvert@7105159b of class UDF.PlatformConvert with arguments {website:org.apache.hadoop.io.Text} of size 1

java.io.IOException: org.apache.hadoop.hive.ql.metadata.HiveException: Unable to execute method public org.apache.hadoop.io.IntWritable UDF.PlatformConvert.evaluate(org.apache.hadoop.io.Text) throws java.lang.Exception  on object UDF.PlatformConvert@7105159b of class UDF.PlatformConvert with arguments {website:org.apache.hadoop.io.Text} of size 1

                  at org.apache.hadoop.hive.ql.exec.FetchTask.fetch(FetchTask.java:154)

Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: Unable to execute method public org.apache.hadoop.io.IntWritable UDF.PlatformConvert.evaluate(org.apache.hadoop.io.Text) throws java.lang.Exception  on object UDF.PlatformConvert@7105159b of class UDF.PlatformConvert with arguments {website:org.apache.hadoop.io.Text} of size 1

                  at org.apache.hadoop.hive.ql.exec.FunctionRegistry.invoke(FunctionRegistry.java:981)

Caused by: java.lang.reflect.InvocationTargetException

                  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

Caused by: java.io.IOException: java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)

Caused by: java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)

                  at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1094)

信息点:提示数据库异常

Access denied for user 'root'@'localhost' (using password:YES)

以上信息大致推断数据库连接异常。

[错误解析]

主要原因:执行自定义UDF函数的节点的和要查询中间表所在数据库不在同一个节点上而连接数据库的URLjdbc:mysql://127.0.0.1:3306/bigdata

解决办法:1.修改中间表所在数据的权限设置

           GRANT ALL PRIVILEGES ON *.* TO'root'@'%' IDENTIFIED BY '123' WITH GRANT OPTION;

              给所有root用户赋予所有权限。这样,即使不在同一节点上也可以相互操作对方的数据库

             2.修改连接数据库的URL

             jdbc:mysql://192.168.23.1:3306/bigdata

                          设置为要操作数据库所对应的ip

             3.重新打包上传,并创建函数

重新执行

执行成功!

 

创建zj,并插入数据

自定义函数platidutfdateidudf同上面的自定义行数作用一致

通过自定义的函数查询,并将对应的属性值转化成上文展示中间表的id

如果将上一步操作查询出来的数据插入到提前定义的表stats_view_depth1

操作语句

from zj

insert into table stats_view_depth1

select platidudf(platform_dimension_id),dateidudf(data_dimension_id),kpi_dimension_id ,pv1,pv2,pv3,pv4,pv5_10,pv10_30,pv30_60, pv60_plus,created ;

执行后报错如下:

后面提示信息:No suitable sriver found for jdbc…,大致意思时没有找到合适的驱动

报错原因:yarn下没找到数据库的驱动包hadoop-2.6.5/share/hadoop/yarn

因为插入操作需要执行mapreduce作业,上文案例,通过自定义函数查询操作,没有执行mapreduce作业,对应的数据库驱动是从hive目录下加载,所以运行正常。

解决办法:将hive目录下的数据库启动拷贝到hadoop-2.6.5/share/hadoop/yarn目录下

再次执行,一切正常。

 

总结:mysql设置远程访问数据库的多种方法

Mysql权限设置正确,但仍无法远程访问。通过telnet发现3306端口未打开。

Mysql默认只绑定127.0.0.1,即:只有在本机才能访问3306端口。

1.    修改配置文件中的bind-address或注释

2.    重启MySQL。再通过远程访问就可以了,telnet可以发现端口也打开了

通过改表法

mysql -u root -p123  

mysql>use mysql;  

update user set host = '%' where user = 'root';  

mysql>select host, user from user;  

 

通过授权法

        1. 从任何主机都可以连接到mysql服务器

  GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'IDENTIFIED BY 'mypassword' WITH GRANT OPTION;

2.指定连接数据库的主机

GRANT ALL PRIVILEGES ON *.* TO root@'192.168.101.234' IDENTIFIED BY 'mypassword' WITH GRANT OPTION;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值