1.文檔編寫目的java
本文檔講述如何開發Hive自定義函數(UDF),以及如何在Impala中使用Hive的自定義函數,經過本文檔,您將學習到如下知識:sql
1.如何使用Java開發Hive的自定義函數shell
2.如何在Hive中建立自定義函數及使用數據庫
3.如何在Impala中使用Hive的自定義函數apache
這篇文檔將重點介紹UDF在Hive和Impala的使用,並基於如下假設:服務器
1.集羣環境正常運行函數
2.集羣安裝Hive和Impala服務工具
如下是本次測試環境,但不是本操做手冊的硬限制:oop
1.操做系統:Redhat6.5學習
2.CDH和CM版本爲5.11.1
3.採用sudo權限的ec2-user用戶進行操做
2.UDF函數開發
使用Intellij工具開發Hive的UDF函數,進行編譯;
1.使用Intellij工具經過Maven建立一個Java工程
2.pom.xml文件中增長Hive包的依賴
<dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-exec</artifactId> <version>1.1.0</version> </dependency>
3.Java示例代碼以下
package com.peach.date; import org.apache.hadoop.hive.ql.exec.UDF; import java.text.ParseException; import java.text.SimpleDateFormat; /** * SQL的UDF日期相關工具類 * Created by peach on 2017/8/24. */ public class DateUtils extends UDF { /** * 將日期字符串格式化爲標準的日期格式 * 如: * 2017-8-9 to 2017-08-09 * 2017-08-09 9:23:3 to 2017-08-0909:23:03 * @param sdate * @param pattern * @return */ public static String evaluate(Stringsdate, String pattern) { String formatDate = sdate; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { formatDate =sdf.format(sdf.parse(sdate)); } catch (ParseException e) { e.printStackTrace(); } return formatDate; } }
此處使用一個簡單的日期轉換自定義函數來作事例,注意此處須要集成UDF類,重寫evaluate方法,來實現本身定義函數。
4.編譯jar包
前提條件是已配置Maven的環境變量,命令行進入工程目錄,執行以下命令:
mvn clean package
3.Hive使用自定義函數(UDF)
將章節2中編譯好的sql-udf-utils-1.0-SNAPSHOT.jar上傳到集羣服務器;
3.1建立臨時UDF
1.進入Hive的shell命令行,執行以下命令,建立臨時函數
add jar /home/ec2-user/sql-udf-utils-1.0-SNAPSHOT.jar;create temporary function parse\_date as 'com.peach.date.DateUtils';
2.在命令行測試該UDF函數
select parse\_date(dates, 'yyyy-MM-dd HH:mm:ss') from date\_test1;
3.2建立永久UDF
1.在HDFS中建立相應目錄,將sql-udf-utils-1.0-SNAPSHOT.jar包上傳至該目錄
ec2-user@ip-172-31-8-141 ~$ hadoop dfs -mkdir /udfjar ec2-user@ip-172-31-8-141 ~$ hadoop dfs -put sql-udf-utils-1.0-SNAPSHOT.jar /udfjar
注意:目錄udfjar和sql-udf-utils-1.0-SNAPSHOT.jar的權限,所屬用戶爲hive
2.進入Hive的shell命令行,執行以下命令建立永久的UDF
create function default.parse\_date as 'com.peach.date.DateUtils' using jar 'hdfs://ip-172-31-9-186.ap-southeast-1.compute.internal:8020/udfjar/sql-udf-utils-1.0-SNAPSHOT.jar';
注意:在建立的時候若是帶有數據庫名,則該UDF函數只對該庫生效,其它庫沒法使用該UDF函數。
3.在命令行測試該UDF
select parse\_date(dates, 'yyyy-MM-dd HH:mm:ss') from date\_test1;
4.驗證永久UDF函數是否生效
從新打開Hive CLI能正常使用建立的UDF函數。
4.Impala使用Hive的UDF
1.在Impala shell命令行執行元數據同步命令
ip-172-31-10-156.ap-southeast-1.compute.internal:21000 > invalidate metadata;
2.使用UDF函數
ip-172-31-10-156.ap-southeast-1.compute.internal:21000 > select parse\_date(dates,'yyyy-MM-dd HH:mm:ss') from date\_test1;
5.常見問題
1.經過Impala CLI命令行,使用UDF自定義函數時異常
Connected to ip-172-31-10-156.ap-southeast-1.compute.internal:21000 Server version: impalad version 2.7.0-cdh5.10.2 RELEASE (build 38c989c0330ea952133111e41965ff9af96412d3) [ip-172-31-10-156.ap-southeast-1.compute.internal:21000] > select parse_date(dates) from date_test1; Query: select parse_date(dates) from date_test1 Query submitted at: 2017-08-24 12:51:44 (Coordinator: http://ip-172-31-10-156.ap-southeast-1.compute.internal:25000) ERROR: AnalysisException: default.parse_date() unknown
元數據未同步致使,執行以下命令進行元數據同步:
[ip-172-31-10-156.ap-southeast-1.compute.internal:21000] > invalidate metadata;
2.在Impala CLI命令行執行,異常以下
[ip-172-31-10-156.ap-southeast-1.compute.internal:21000] > select parse_date(dates,'yyyy-MM-dd HH:mm:ss') from date_test1; Query: select parse_date(dates,'yyyy-MM-dd HH:mm:ss') from date_test1 Query submitted at: 2017-08-24 13:02:14 (Coordinator: http://ip-172-31-10-156.ap-southeast-1.compute.internal:25000) ERROR: Failed to copy hdfs://ip-172-31-9-186.ap-southeast-1.compute.internal:8020/udfjar/sql-udf-utils-1.0-SNAPSHOT.jar to /var/lib/impala/udfs/sql-udf-utils-1.0-SNAPSHOT.2386.2.jar: Error(2): No such file or directory
在Impala Daemon服務器上,目錄不存在致使
解決方法:
在全部Impala Daemon服務器建立/var/lib/impala/udfs目錄
[ec2-user@ip-172-31-10-156 lib]$ sudo mkdir -p impala/udf [ec2-user@ip-172-31-10-156 lib]$ sudo chown -R impala:impala impala/
注意:目錄所屬用戶及組