如何使用 Apache IoTDB 中的 UDF

news2024/11/15 16:45:43

本篇作者:

IoTDB 社区 -- 廖兰

本文将概述用户使用 UDF 的大致流程,UDF 的详细使用说明请参考官网用户手册:

https://iotdb.apache.org/zh/UserGuide/Master/Operators-Functions/User-Defined-Function.html

1

编写 UDF

IoTDB 为用户提供编写 UDF 的 JAVA API,用户可以自主实现 UDTF 类,IoTDB 将通过类加载机制装载用户编写的类。

1.1

Maven 依赖

如果您使用 Maven,可以从 Maven 库中搜索下面示例中的依赖。请注意选择和目标 IoTDB 服务器版本相同的依赖版本,本文中使用 1.0.0 版本的依赖。

<dependency>
  <groupId>org.apache.iotdb</groupId>
  <artifactId>udf-api</artifactId>
  <version>1.0.0</version>
  <scope>provided</scope>
</dependency>

1.2

实现接口

UDTF 目前有如下接口:

31a4ef8fd497de811ffc3d33ea4f974b.png

在一个完整的 UDTF 实例生命周期中,各个方法的调用顺序如下:

1. void validate(UDFParameterValidator validator) throws Exception
2. void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) throws Exception
3. void transform(Row row, PointCollector collector) throws Exception
// 或者
void transform(RowWindow rowWindow, PointCollector collector) throws Exception
4. void terminate(PointCollector collector) throws Exception
5. void beforeDestroy()

注意,框架每执行一次 UDTF 查询,都会构造一个全新的 UDF 类实例,查询结束时,对应的 UDF 类实例即被销毁,因此不同 UDTF 查询(即使是在同一个 SQL 语句中)UDF 类实例内部的数据都是隔离的。您可以放心地在 UDTF 中维护一些状态数据,无需考虑并发对 UDF 类实例内部状态数据的影响。

UDTF 有较为完善的 Javadoc 说明,在编码实现 UDTF 类前,阅读说明可以帮助您更好的使用 UDTF。

1.3

注意事项

下面列出在实现 UDTF 的一些接口时需要注意的地方。

1.3.1 validate 接口

/**
 * This method is mainly used to validate {@link UDFParameters} and it is executed before {@link
 * UDTF#beforeStart(UDFParameters, UDTFConfigurations)} is called.
 *
 * @param validator the validator used to validate {@link UDFParameters}
 * @throws Exception if any parameter is not valid
 */
@SuppressWarnings("squid:S112")
default void validate(UDFParameterValidator validator) throws Exception {}

该接口在初始化方法 beforeStart 调用前执行,用于检测 UDFParameters 中用户输入的参数是否合法。

同时,可以检测作为输入的时间序列的数据类型是否符合预期,比如以如下方式实现该接口:

@Override
public void validate(UDFParameterValidator validator) throws Exception {
  validator
      // this udf only accepts 1 time series
      .validateInputSeriesNumber(1)
      // the data type of the first input time series should be INT32
      .validateInputSeriesDataType(0, Type.INT32)
      // this udf doesn't accept any extra parameters
      // the validation rule is not required because extra parameters will be ignored
      .validate(
          attributes -> ((Map) attributes).isEmpty(),
          "extra udf parameters are not allowed",
          validator.getParameters().getAttributes());
}

那么该 UDF 将只能接受 INT32 类型的时间序列作为输入,其它类型的序列作为输入将报错:

3ba376ba38cf72c6f76cb71887205788.png

INT32 类型的序列正常执行查询:

bb1ce9c7d3729e620e6fa96650cc2312.png

1.3.2 beforeStart 接口

void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) throws Exception

该接口是 UDTF 类必须实现的接口,可以指定 UDF 访问原始数据时采取的策略和输出结果序列的类型,最简单的实现方式如下:

@Override
public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
  configurations.setAccessStrategy(new RowByRowAccessStrategy()).setOutputDataType(Type.INT32);
}

上述实现表明该 UDF 将逐行访问数据并调用相应的 transform 方法,同时,该 UDF 的 transform 方法的 PointCollector 将只能接收 INT32 类型的数据,如果接收其它类型的数据可能会出现运行时错误,具体可以参考 UDTF Javadoc。可以参考如下的简单实现方式:

@Override
public void transform(Row row, PointCollector collector) throws IOException {
  if (!row.isNull(0)) {
    // 由于 beforeStart 方法中设置了 outPutDataType 为 INT32
    // 这里如果调用 collector.putFloat(row.getTime(), -row.getInt(0)) 可能会出现运行时错误
    collector.putInt(row.getTime(), -row.getInt(0));
  }
}

这样实现之后,查询效果可以理解成将每一行数据取负:

7882065c1c8f5332552d7b9fe4e15a2e.png

1.3.3 transform 接口

transform 接口有两种参数列表,具体调用哪一种由实现的 UDF beforeStart 接口中设置的 AccessStrategy 类型决定。如果 AccessStrategy 类型为 XXXWindowStrategy,则会调用下述 transfrom:

/**
 * When the user specifies {@link SlidingSizeWindowAccessStrategy} or {@link
 * SlidingTimeWindowAccessStrategy} to access the original data in {@link UDTFConfigurations},
 * this method will be called to process the transformation. In a single UDF query, this method
 * may be called multiple times.
 *
 * @param rowWindow original input data window (rows inside the window are aligned by time)
 * @param collector used to collect output data points
 * @throws Exception the user can throw errors if necessary
 * @see SlidingSizeWindowAccessStrategy
 * @see SlidingTimeWindowAccessStrategy
 */
@SuppressWarnings("squid:S112")
default void transform(RowWindow rowWindow, PointCollector collector) throws Exception {}

由于入参 RowWindow 时按照原始数据划分的窗口,在访问窗口数据时有几点需要注意:

1. 窗口可能为空,此时访问窗口内具体某一行可能报越界异常,所以建议在访问具体数据前检查 if(rowWindow.windowSize() > 0)

2. 目前 PointCollector 只支持将特定时间戳放入一次,如果同一时间戳被多次放入,则可能非预期地终止计算。而在进行窗口的运算的时候,需要选取窗口中某一行的时间戳作为这个窗口结果的时间戳,在特定数据场景下,这种使用可能会由于窗口重叠造成同一时间戳被多次放入 PointCollector 而导致非预期的结果。如果要避免这种情况,可以选择使用 RowWindow 提供的 windowStartTime() 或者 windowEndTime() 作为窗口结果的时间戳。

可以参考下述实现:

public void transform(RowWindow rowWindow, PointCollector collector) throws Exception {
  long result = 0L;


  for (int i = 0; i < rowWindow.windowSize(); ++i) {
    if (!rowWindow.getRow(i).isNull(0)) {
      result += rowWindow.getRow(i).getLong(0);
    }
  }


  // 这里使用 rowWindow.windowStartTime() 而非 rowWindow.getRow(0).getTime()
  collector.putLong(rowWindow.windowStartTime(), result);
}

2

注册UDF

注册一个 UDF 可以按如下流程进行:

  1. 实现一个完整的 UDF 类,假定这个类的全类名为

org.apache.iotdb.udf.UDTFExample

2. 将项目打成 JAR 包

3. 进行注册前的准备工作,根据注册方式的不同需要做不同的准备,具体可参考示例

4. 使用以下 SQL 语法注册 UDF

CREATE FUNCTION <UDF-NAME> AS <UDF-CLASS-FULL-PATHNAME> (USING URI URI-STRING)?

完成注册后即可以像使用内置函数一样使用注册的 UDF 了。

2.1

注册方式示例

注册名为 example 的 UDF,以下两种注册方式任选其一即可。

2.1.1 不指定 URI

准备工作: 

使用该种方式注册时,需要提前将 JAR 包放置到目录 iotdb-server-1.0.0-all-bin/ext/udf(该目录可配置) 下。 

注意,如果使用的是集群,那么需要将 JAR 包放置到所有 DataNode 的该目录下。

放置完成后使用注册语句:

CREATE FUNCTION example AS 'org.apache.iotdb.udf.UDTFExample'

2.1.2 指定 URI

准备工作: 

使用该种方式注册时,您需要提前将 JAR 包上传到服务器上并确保执行注册语句的 IoTDB 实例能够访问该服务器。 

指定 URI 后无需手动放置 JAR 包到指定目录,IoTDB 会下载 JAR 包并正确同步到整个集群。

注册语句:

CREATE FUNCTION example AS 'org.apache.iotdb.udf.UDTFExample' USING URI 'http://jar/example.jar'

2.2

注意事项

1. 1.0.0 版本的 UDF API 包路径与之前版本的 IoTDB 不同,因此 1.0.0 版本的 IoTDB 实例并不能注册 0.13 及之前版本已经构建好的 UDF jar 包。可以通过更新 UDF 依赖版本,重新 import 正确路径的 UDF API,再构建 jar 包的方式更新 UDF 实现至 1.0.0 及以上版本。

2. 由于 IoTDB 的 UDF 是通过反射技术动态装载的,因此在装载过程中无需启停服务器。

3. UDF 函数名称是大小写不敏感的。

4. 请不要给 UDF 函数注册一个内置函数的名字。使用内置函数的名字给 UDF 注册会失败。

5. 不同的 JAR 包中最好不要有全类名相同但实现功能逻辑不一样的类。例如 UDF(UDAF/UDTF):udf1、udf2 分别对应资源 udf1.jar、udf2.jar。如果两个 JAR 包里都包含一个

org.apache.iotdb.udf.UDTFExample 类,当同一个 SQL 中同时使用到这两个 UDF 时,系统会随机加载其中一个类,导致 UDF 执行行为不一致。

a7913d8ea2ae1a2a86823aaad99f74e4.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/187866.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

opensuse15.4安装android-studio-2021.1.1.23_未完成

opensuse15.4安装android_studio再运行微信apk_未完成 未完成的原因是&#xff1a;本人台式机的物理内存为4G&#xff0c;官方要求是16G android studio与android sdkj是两个完全不同的两样东西。 Android studio是一个IDE&#xff08;可视化开发工具&#xff09;跟eclipse一…

SAP 新准则IFRS 17:重新思考和革新保险会计的机会

您准备好迎接 IFRS 17 了吗&#xff1f;财务报告准则过去曾多次更改&#xff0c;但这次没有。这一变化将为准备迎接新准则的保险公司带来广泛的机遇。许多公司都有应对这些要求的战术计划。但最大的成功将由制定包括 IFRS 17 在内的更广泛报告战略的公司实现。他们不会做出回应…

redis-哈希槽一致hash算法

1、一致性hash算法&#xff1f; 以分布式缓存为例&#xff0c;假设现在有3台缓存服务器(S0&#xff0c;S1&#xff0c;S2)&#xff0c;要将一些图片尽可能平均地分配到不同的服务器上&#xff0c;hash算法的做法是&#xff1a; (1) 以图片的名称作为key&#xff0c;然后对其做…

【Unity3D插件】UniRx(基于Unity的响应式编程框架)插件教程

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客QQ群&#xff1a;1040082875 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、介绍UniRx插件 UniRx是一种基于Unity3D的…

九龙证券|石墨烯电池和锂离子电池哪个好

电池技术是电动汽车大力推广和开展的最大门槛&#xff0c;而电池工业正处于铅酸电池和传统锂电池开展均遇瓶颈的阶段&#xff0c;石墨烯储能设备的研制成功后&#xff0c;若能批量生产&#xff0c;则将为电池工业乃至电动车工业带来新的改造。那么石墨烯电池和锂离子电池哪个更…

VUE VS React 对比

VUE VS React 对比 这是面试中经常考察的一个问题&#xff0c;简单整理一下。我主要写 react &#xff0c;所以 react 的特点阐述的多一点。 语法格式 vue 是单独的文件格式&#xff0c;一个文件包括了 js css HTML 全部 React 通常是 jsx 格式&#xff0c;JS 和 HTML 写在…

shiro相关源码解析

1. 认证过程相关源码解析 前后文可接查看 shiro的登陆都是通过subject.login()方法实现&#xff0c;接下来我们就进入login方法查看实现过程&#xff1a; 1.1 进入DelegatingSubject类的login方法&#xff1a; 此类实现了Subject接口&#xff1a; public void login(Authen…

基于ssm的高校二手物品交易网 java idea mysql

本文论述了民办高校二手物品交易网的设计和实现&#xff0c;该网站从实际运用的角度出发&#xff0c;运用了计算机网站设计、数据库等相关知识&#xff0c;网络和Mysql数据库设计来实现的&#xff0c;网站主要包括用户注册、用户登录、浏览商品、搜索商品、查看商品并进行购买&…

bilibili全链路压测改造之全链自动化测试实践

01 、背景与意义 B站直播营收送礼业务有着高写、在跨晚和S赛等大型活动下流量陡增、数据实时性要求高等特性&#xff0c;传统压测对于写场景为了避免影响线上数据做了各种屏蔽和黑名单处理&#xff0c;有着无法逼近线上真实情况的问题&#xff0c;因此业务对全链路压测有着较大…

拿下阿里自动化测试岗23k*14薪offer的全程面试记录解析以及总结,一面二面三面,项目,功能,自动化,性能测试,面试题问答

一、自我介绍 面试官您好&#xff01;我叫xx&#xff0c;来自深圳&#xff0c;毕业之后一直从事于软件测试的工作&#xff0c;有做过保险、金融、电商等项目&#xff1b;有做过做功能测试、接口测试&#xff0c;自动化测试&#xff0c;在工作中积极主动、可以独立的完成测试工…

shiro(一):shiro基本概念及基本使用(认证、授权)

1. 权限的管理 1.1 什么是权限管理 基本上涉及到用户参与的系统都要进行权限管理&#xff0c;权限管理属于系统安全的范畴&#xff0c;权限管理实现对用户访问系统的控制&#xff0c;按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资源。 权限管理包括用…

算法刷题打卡第76天:判断矩阵是否是一个 X 矩阵

判断矩阵是否是一个 X 矩阵 难度&#xff1a;简单 如果一个正方形矩阵满足下述 全部 条件&#xff0c;则称之为一个 X 矩阵 &#xff1a; 矩阵对角线上的所有元素都 不是 0 矩阵中所有其他元素都是 0 给你一个大小为 n x n 的二维整数数组 grid &#xff0c;表示一个正方形矩…

CV——day72:从零开始学YOLO——YOLO-v3(可以在我的资源里下载完整的v1到v3的笔记啦!)

YOLO-v36. YOLO-v36.1 YOLO-v3 改进综述6.2 多scale方法改进与特征融合6.3 经典变换方法对比分析6.4 残差连接方法解读6.5 整体网络模型架构分析6.6 先验框设计改进6.7 softmax层改进6. YOLO-v3 **tips&#xff1a;**作者本人因为美军广泛运用于军事领域&#xff0c;所以决定不…

基于php电影点播平台/电影网站

摘要网络技术给生活带来了十分的便利。所以把电影点播平台与现在网络相结合。在点播平台发展的整个过程中&#xff0c;电影信息管理担负着最重要的角色。为满足如今日益复杂的管理需求&#xff0c;各类电影信息管理程序也在不断改进。本课题所设计的电影点播平台&#xff0c;使…

张艺谋《满江红》起诉自媒体人,杨语莲推荐周兆成意在下个谋女郎

伴随着兔年春节的到来&#xff0c;又迎来一波贺岁剧热潮&#xff0c;著名导演张艺谋的《满江红》&#xff0c;也如期和观众朋友见面。随着春节的逐渐结束&#xff0c;贺岁电影《满江红》票房&#xff0c;也再次创下了新高&#xff0c;关于这部电影的话题也多了起来。 最引人关注…

中国电子学会2021年12月份青少年软件编程Python等级考试试卷一级真题(含答案)

青少年软件编程&#xff08;Python&#xff09;等级考试试卷&#xff08;一级&#xff09; 一、单选题(共25题&#xff0c;共50分) 1. 昨天的温度是5摄氏度&#xff0c;今天降温7摄氏度&#xff0c;今天的温度是多少摄氏度&#xff1f;&#xff08; &#xff09; A. 12 …

利用ChatGPT自动编写下载高德地图poi数据的代码

最近ChatGPT很火&#xff0c;它自己对于自己的解释如下图。我们可以让它来帮我们写代码&#xff0c;属于是薅机器人羊毛了。 首先注册账号&#xff0c;可百度&#xff0c;如&#xff1a;【教程】ChatGPT 保姆级注册教程&#xff0c;但中国大陆手机号不支持OpenAI的注册服务&am…

进程概念(PCB、进程创建、进程状态等)

进程是一个运行的程序&#xff0c;是所有计算机的基础。这个过程与计算机代码不一样&#xff0c;尽管它们非常相似。程序通常被认为是 “被动的” 实体&#xff0c;而进程则是 “主动的” 实体。硬件状态、RAM、CPU和其它属性都是进程持有的属性。下面我们就来了解更多关于进程…

活体识别1:近红外(NIR)图像特性

说明 最近在接触活体识别&#xff0c;在网上找到一个介绍近红外光&#xff08;NIR&#xff09;特性的论文&#xff0c;我简单做个笔记。原文的全文在文末参考资料里。 来自&#xff1a;[1]隋孟君,茅耀斌,孙金生.基于近红外图像特征的活体人脸检测[J].自动化与仪器仪表,2021(0…

Win10下使用WSL2

打包 wsl --export Ubuntu-20.04 E:\Ubuntu\ubuntu.tar.gz 注销之前 wsl --unregister Ubuntu-20.04 导入 wsl --import Ubuntu-20.04 E:\Ubuntu\ E:\Ubuntu\ubuntu.tar.gz --version 2 设置默认登陆用户为安装时用户名 ubuntu2004.exe config --default-user dwb 更新清…