
# 开发和部署对接HetuEngine的Hive UDF
#### 操作场景
HetuEngine是一个高性能实时分析数据库，支持用户自定义一些函数，用于扩展SQL以满足个性化的需求，这类函数称为UDF。
本章节主要介绍开发和应用Hive UDF的具体步骤。
#### 约束与限制
MRS 3.2.1及以后版本，需要基于JDK17.0.4及以上版本开发。本章节以MRS 3.3.0版本为例。
#### 开发Hive UDF项目
本样例实现一个Hive UDF，说明见下表。
表1Hive UDF说明 
| 名称         | 说明          |
|:---|:---|
| AutoAddOne | 对输入的数字加1后返回 |
   
![](https://support.huaweicloud.com/cmpntguide-lts-mrs/public_sys-resources/note_3.0-zh-cn.png)
- 一个普通Hive UDF必须继承自"org.apache.hadoop.hive.ql.exec.UDF"。
- 一个普通Hive UDF必须至少实现一个evaluate()方法，evaluate方法支持重载。
- 当前只支持以下数据类型：
  - boolean、byte、short、int、long、float、double
  
  - Boolean、Byte、Short、Int、Long、Float、Double
  
  - List、Map
  
  
  目前暂不支持除以上类型外的更复杂数据类型的UDF、UDAF和UDTF。
  
- 当前只支持入参数量小于或等于5个的Hive UDF，大于5个入参的Hive UDF将无法被注册。
- 如果Hive UDF入参为null，系统调用Hive UDF将直接返回null，不会解析null作为入参的Hive UDF逻辑，这可能导致处理null值的Hive UDF执行结果与Hive执行结果不一致。
- 需要在maven工程中添加hive-exec-3.1.1的依赖，可从Hive服务安装目录下获取。
- （可选）若用户存在Hive UDF依赖的配置文件，建议将其作为资源文件放在resources目录下，即可打包到Hive UDF函数包中。
 
1. 创建Maven项目，"groupId"配置"com.test.udf"，"artifactId"配置"udf-test"。这两个值可根据实际情况自定义。
2. 修改"pom.xml"文件如下： 
   ```
   <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <modelVersion>4.0.0</modelVersion>
          <groupId>com.test.udf</groupId>
          <artifactId>udf-test</artifactId>
          <version>0.0.1-SNAPSHOT</version>
          <dependencies>
            <dependency>
               <groupId>org.apache.hive</groupId>
               <artifactId>hive-exec</artifactId>
               <version>3.1.1</version>
            </dependency>
          </dependencies>
          <build>
            <plugins>
               <plugin>
                   <artifactId>maven-shade-plugin</artifactId>
                   <executions>
                       <execution>
                           <phase>package</phase>
                           <goals>
                               <goal>shade</goal>
                           </goals>
                       </execution>
                   </executions>
               </plugin>
               <plugin>
                   <artifactId>maven-resources-plugin</artifactId>
                   <executions>
                       <execution>
                           <id>copy-resources</id>
                           <phase>package</phase>
                           <goals>
                               <goal>copy-resources</goal>
                           </goals>
                           <configuration>
                               <outputDirectory>${project.build.directory}/</outputDirectory>
                               <resources>
                                   <resource>
                                       <directory>src/main/resources/</directory>
                                       <filtering>false</filtering>
                                   </resource>
                               </resources>
                           </configuration>
                       </execution>
                   </executions>
               </plugin>
            </plugins>
          </build>
   </project>
   ```
   
   
3. 创建Hive UDF实现类。 
   ```
   import org.apache.hadoop.hive.ql.exec.UDF; 
   /** 
    * AutoAddOne 
    * 
    * @since 2020-08-24 
    */ 
   public class AutoAddOne extends UDF { 
       public int evaluate(int data) { 
           return data + 1; 
       } 
   }
   ```
   
   
4. 打包Maven项目，target目录下的udf-test-0.0.1-SNAPSHOT.jar文件即为Hive UDF函数包。 
   需要将所有依赖文件都打包到jar包里。
   
   
 
#### 配置Hive UDF
用户通过在配置文件"udf.properties"中添加注册信息来注册Hive UDF，需按"函数名称 类路径"格式添加每一行内容：
以"udf.properties"为例，已明确要注册的四个Hive UDF：
```
booleanudf io.hetu.core.hive.dynamicfunctions.examples.udf.BooleanUDF
shortudf io.hetu.core.hive.dynamicfunctions.examples.udf.ShortUDF
byteudf io.hetu.core.hive.dynamicfunctions.examples.udf.ByteUDF
intudf io.hetu.core.hive.dynamicfunctions.examples.udf.IntUDF
```
- 如果用户添加的Hive UDF注册信息有误，比如错误的格式或者不存在的类路径，系统将忽略这些错误的注册信息，并打印相应日志。
- 如果用户注册重复的Hive UDF，系统将只注册一次，并忽略重复的注册。
- 如果用户注册的Hive UDF与系统内部注册的相同，系统将会发生异常并无法正常启动。解决该异常需要用户删除对应的Hive UDF注册信息。
 
#### 部署Hive UDF
要在HetuEngine中使用Hive UDF，需要用户将相应的UDF函数包、"udf.properties"、UDF依赖的配置文件上传到指定HDFS路径，例如"/user/hetuserver/udf/"，并重启HetuEngine计算实例。
1. 创建"/user/hetuserver/udf/data/externalFunctions"文件夹，将"udf.properties"放在"/user/hetuserver/udf"，将UDF函数包放在"/user/hetuserver/udf/data/externalFunctions"，将UDF依赖的配置文件放在"/user/hetuserver/udf/data"。 
   - 使用HDFS的页面上传。
     1. 使用*HetuEngine* *用户*登录FusionInsight Manager，选择"集群 \> 服务 \> HDFS"，进入HDFS服务页面。
     
     2. 在概览页签下的"基本信息"区域，单击"NameNode WebUI"后的链接，进入NameNode WebUI界面。
     
     3. 选择"Utilities \> Browse the file system"，单击![](https://support.huaweicloud.com/cmpntguide-lts-mrs/zh-cn_image_0000001910116408.png)创建"/user/hetuserver/udf/data/externalFunctions"。
     
     4. 进入"/user/hetuserver/udf"，单击![](https://support.huaweicloud.com/cmpntguide-lts-mrs/zh-cn_image_0000001944035621.png)上传"udf.properties"。
     
     5. 进入"/user/hetuserver/udf/data/"，单击![](https://support.huaweicloud.com/cmpntguide-lts-mrs/zh-cn_image_0000001910156428.png)上传UDF依赖的配置文件。
     
     6. 进入"/user/hetuserver/udf/data/externalFunctions"，单击![](https://support.huaweicloud.com/cmpntguide-lts-mrs/zh-cn_image_0000001910116416.png)上传UDF函数包。
      
   
   
   
   - 使用HDFS命令行上传。
     1. 登录HDFS服务客户端所在节点，切换到客户端安装目录，例如"/opt/client"。
        ```
        cd /opt/client
        ```
        
     
     2. 执行以下命令配置环境变量。
        ```
        source bigdata_env
        ```
        
     
     3. 如果集群已启用Kerberos认证（安全模式），执行以下命令进行用户认证。集群未启用Kerberos认证（普通模式）无需执行用户认证。
        ```
        kinit HetuEngine用户
        ```
        根据回显提示输入密码。
        
     
     4. 执行如下命令创建目录。
        ```
        hdfs dfs -mkdir -p /user/hetuserver/udf/data/externalFunctions
        ```
        将已准备好相应的UDF函数包、"udf.properties"、UDF依赖的配置文件上传到目录路径。
        ```
        hdfs dfs -put ./UDF依赖的配置文件 /user/hetuserver/udf/data
        hdfs dfs -put ./udf.properties/user/hetuserver/udf
        hdfs dfs -put ./UDF函数包/user/hetuserver/udf/data/externalFunctions
        ```
        
      
   
   
   
   
2. 重启HetuEngine计算实例。
#### 使用Hive UDF
使用客户端访问：
1. 进入HetuEngine客户端。
2. 执行如下命令应用Hive UDF： **select AutoAddOne(1);**
   ```
   select AutoAddOne(1);
   _col0
   -------
        2
   (1 row)
   ```
   
 
