# 概述
#### 功能描述
Remote UDF（Remote User-Defined Function，远程用户自定义函数）是指将UDF的执行逻辑从主计算引擎剥离，主引擎通过标准接口（如 HTTP、gRPC、Thrift）调用该服务完成计算。Remote UDF将计算逻辑与主引擎分离、实现资源解耦，充分提升Remote UDF复用性与灵活性。
本节内容以FunctionGraph作为Remote UDF 的执行载体，介绍开发Remote UDF到计算引擎调用的操作步骤。
了解更多：
- [UDF与Remote UDF的对比]
- [UDF、UDAF和UDTF的对比]
 
#### 方案优势
Remote UDF（User Defined Functions）的优势在于风险隔离、资源解耦与成本优化。
- 风险隔离：当关键生产环境需要执行UDF时，直接修改UDF存在执行风险。 通过Remote UDF将计算逻辑卸载到函数工作流FunctionGraph，既能保持业务功能，又能通过无服务器架构实现风险隔离。
  
- 资源解耦：对于大模型推理等计算密集型任务，为避免在Spark等集群中长期占用昂贵资源，兼顾功能需求、稳定性和成本效益，将计算密集型操作剥离至FunctionGraph执行
- 成本优化：Remote UDF将default队列还原为纯数据通道，消除UDF引发的风险，使其能为用户提供更经济，更安全的核心数据流服务。
 
#### 约束与限制
Remote UDF只对单行数据产生作用，适用于单进单出的场景。
#### 环境准备
使用FunctionGraph开发调试Remote UDF时，您需要先安装IDEA并配置Maven，下载依赖JAR包并配置FunctionGraph服务，做好Remote UDF开发前准备工作。
表1UDF开发环境 
| 准备项                 | 说明                                                                                                                                                                                                          |
|:---|:---|
| 操作系统              | Windows系统，支持Windows7以上版本。                                                                                                                                                                                  |
| 安装JDK               | JDK使用1.8版本。                                                                                                                                                                                                 |
| 安装和配置IntelliJ IDEA | IntelliJ IDEA为进行应用开发的工具，版本要求使用2019.1或其他兼容版本。                                                                                                                                                               |
| 安装Maven           | 开发环境的基本配置。用于项目管理，贯穿软件开发生命周期。                                                                                                                                                                               |
| 下载依赖JAR包         | 依赖引入下载Jar包：spark-function-sdk_2.13-jar-with-dependencies.jar 获取方式：从https://repo.huaweicloud.com/repository/maven/huaweicloudsdk/地址下载。 |
   
#### 开发流程
Remote UDF函数开发流程参考如下：
图1开发流程   
![](https://support.huaweicloud.com/devg-aidatalake/zh-cn_image_0000002701306787.png "点击放大")
表2开发流程说明 
| 序号  | 阶段                               | 操作界面                 | 说明                                                   |
|:---|:---|:---|:---|
| 1   | 新建Maven工程，配置Project structure | IntelliJ IDEA         |  编写Remote UDF函数代码。                        |
| 2   | 编写Remote UDF函数代码                | IntelliJ IDEA         |  编写Remote UDF函数代码。                        |
| 3   | 调试，编译代码并导出Jar包               | IntelliJ IDEA         |  编写Remote UDF函数代码。                        |
| 4 | 创建FunctionGraph函数，并上传Jar包    | OBS控制台               | 将生成的UDF函数Jar包文件上传到已创建的FunctionGraph函数中。              |
| 5 | 创建Remote UDF函数               | DataArts Studio控制台 | 在DataArts Studio控制台的"脚本开发"界面，创建UDF函数。                 |
| 6  | 验证和使用Remote UDF函数              | DataArts Studio控制台   | 在DataArts Studio控制台的"作业开发"界面，Spark SQL作业中使用创建的UDF函数。 |
   
 #### UDF与Remote UDF的对比
- UDF：适合对性能要求高且熟悉查询引擎开发语言的场景。执行效率高，但开发灵活性和安全性相对较低。
- Remote UDF：适合需要调用外部服务、使用多种语言开发或对开发语言灵活性要求高的场景。具有较高的安全性和开发灵活性。
表3UDF与Remote UDF的对比 
| 特性    | UDF                          | Remote UDF                |
|:---|:---|:---|
| 执行方式  | 在查询引擎本地执行                   | 通过调用函数托管服务执行                |
| 安全性   | 若UDF代码不稳定，可能影响查询引擎进程           | 执行失败仅影响UDF自身，不会导致整体作业进程。   |
| 性能      | 执行效率高                        | 但在向量化和批处理模式下，性能与本地UDF相当      |
| 开发灵活性 | 与查询引擎代码耦合度高，开发限制较多              | 灵活，可调用任意其他服务或程序库，满足多样业务需求  |
| 开发成本  | 需熟悉查询引擎的开发环境和语言，开发成本较高         | 一次性开发投入，开发成本相对较低            |
| 适用场景   | 对性能要求极高的场景，且开发团队熟悉查询引擎的开发语言 | 对开发语言灵活性要求高、需要调用外部服务或程序库的场景 |
   
 #### UDF、UDAF和UDTF的对比
- UDF：创建一个计算两个数字之和的函数。
- UDAF：创建一个计算平均值的函数。
- UDTF：创建一个函数，用于将一个包含多个值的字符串拆分成多行。
表4UDF、UDAF和UDTF的对比 
| 特性   | UDF（User-Defined Function） | UDAF（User-Defined Aggregate Function） | UDTF（User-Defined Table-Generating Function） |
|:---|:---|:---|:---|
| 输入参数 | 一行数据的一个或多个字段               | 多行数据的多个字段                             | 一行或多行数据的一个或多个字段                           |
| 输出结果   | 单个标量值                      | 单个聚合结果                               | 多行数据，每行可以有多个字段                              |
| 主要用途 | 简单的数据转换和计算，如字符串处理、数学运算等   | 数据聚合计算，如求和、平均值、计数等                   | 数据展开和复杂结构解析，如拆分字符串、展开数组等                   |
   
- **UDF示例** ：
  创建一个函数，将输入的数字加1。
  ```
  CREATE FUNCTION add_one AS 'com.example.AddOneUDF';
  SELECT add_one(age) FROM users;
  ```
  假设users表中有一列age，值为25，该函数会输出26。
  
- **UDAF示例** ：
  计算某一列的最大值。
  ```
  CREATE FUNCTION max AS 'com.example.MaxUDAF';
  SELECT max(age) FROM users;
  ```
  假设users表中有一列age，值为25, 30, 35，该函数会输出35。
  
- **UDTF示例** ：
  将一个JSON字符串解析为多行数据。
  ```
  CREATE FUNCTION parse_json AS 'com.example.ParseJsonUDTF';
  SELECT parse_json(json_column) FROM users;
  ```
  假设users表中有一列json_column，值为'{"name":"Alice","age":25},{"name":"Bob","age":30}'，该函数会输出两行，每行包含解析后的name和age字段。
  
 
