自定義UDF函數應用異常java
版權聲明:本文爲yunshuxueyuan原創文章。
如需轉載請標明出處: http://www.cnblogs.com/sxt-zkys/
QQ技術交流羣:299142667mysql
定義函數PlatformConvert:web
實現傳入hive表中string類型字段,經過查詢中間表,返回int類型主鍵id值sql
public class PlatformConvert extends UDF{ public IntWritable evaluate(Text s) throws Exception{ if(s==null){ return null; } PlatformDimension platformDimension = new PlatformDimension(s.toString()); IDimensionConverter convert = new DimensionConverterImpl(); int id=0; id = convert.getDimensionIdByValue(platformDimension); return new IntWritable(id); } }
UDF函數功能:例如參數爲all,返回值爲1;參數爲website,返回值爲2. 數據庫
將定義好的UDF函數上傳到虛擬機,並建立函數名稱爲p_con的臨時函數apache
add jar /root/data/Fun.jar; create temporary function p_con as 'myudf.DateConvert';
建立stats_view_depth_tmp表 服務器
查詢表stats_view_depth_tmp,並將pl字段值轉化成中間表對應的id函數
報錯內容大體意思爲:不能執行自定義的函數oop
出現以上錯誤可能的狀況fetch
具體錯誤信息還需將進一步查看日誌,只列出了關鍵信息
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函數的節點的和要查詢中間表所在數據庫不在同一個節點上而鏈接數據庫的URL爲jdbc: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表,並插入數據
自定義函數platidutf,dateidudf同上面的自定義行數做用一致
經過自定義的函數查詢,並將對應的屬性值轉化成上文展現中間表的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權限設置正確,但仍沒法遠程訪問。經過telnet發現3306端口未打開。
Mysql默認只綁定127.0.0.1,即:只有在本機才能訪問3306端口。
經過改表法
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;