自定義UDF函數應用異常

自定義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

  1. jar不包含全部依賴項。可能不包括全部的依賴關係致使不能加載對應依賴的類信息。
  2. JVM版本不一樣致使。若是使用jdk8進行編譯,而且集羣運行jdk7,那麼它也將失敗
  3. 蜂巢版本。有時候,蜂巢API變化很小,足夠不兼容。可能不是這種狀況,可是確保集羣中擁有相同版本的hadoophive來編譯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,並插入數據

 

自定義函數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設置遠程訪問數據庫的多種方法

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;

相關文章
相關標籤/搜索