阿里云Flink UDF函数使用Demo

该文章会随着学习深度会不断更新,希望大家一起交流和学习

参考文章:
Flink官网
阿里云Flink官网

更新时间戳:
23-11-15 增加UDF多输入实例(聚合性UDF)
23-11-16 增加UDSF使用(目的来一条数据处理一条)

实现流程

聚合类型UDF实现

官网讲的是max函数的实现流程哈,具体如下图
我平常学的话,会先把处理逻辑理清楚,再去看具体实现的代码。
回到问题本身,首先表中的数据怎么读,读到哪里,怎么存,然后就是怎么分析了,最后输出到哪里?
读我是不知道怎么读的,后期看看那个Flink SQL解析怎么搞。
存在什么数据结构里面,自己建个类,需要什么值就写什么值。
createAccumulator() --> return 自建类
accumulator() --> 存储计算逻辑
getvalue() --> 获取最终的值

大概逻辑就是说,我先创建一个自定义的数据结构,里面的存储变量是临时存储着计算的结果(有点像状态哈,内存状态,OOM触发,啥也没了),每来一条流数据,accumulator()处理一下,更新一下数据结构里面的的值(准确的来说,它是对象,不然怎么实现持续更新嘞),水位线触发或者来一条算一条,调用getvalue()获取结果给你看。
在这里插入图片描述

代码细节

实现聚合函数,这里注意,不同函数是继承不一样的类的,此处是继承AggregateFunction
我只实现了基本的参数,剩下的可选的,我是直接没选的
在这里插入图片描述

// 官方提供的代码
import org.apache.flink.table.functions.AggregateFunction;

import java.util.Iterator;

public class ASI_UDAF {
	public static class AccSum {
		public long sum;
	}

	public static class MySum extends AggregateFunction<Long, AccSum> {

		@Override
		public Long getValue(AccSum acSum) {
			return acSum.sum;
		}

		@Override
		public AccSum createAccumulator() {
			AccSum acCount = new AccSum();
			acCount.sum = 0;
			return acCount;
		}

		public void accumulate(AccSum acc, long num) {
			acc.sum += num;
		}

		/**
		 * Support retract a msg generated by upstream operator.
		 * 支持回撤操作
		 */
		public void retract(AccSum acc, long num) {
			acc.sum -= num;
		}

		/**
		 * Support local-global two stage aggregate optimization.
		 * 支持两阶段聚合
		 */
		public void merge(AccSum acc, Iterable<AccSum> it) {
			Iterator<AccSum> iter = it.iterator();
			while (iter.hasNext()) {
				AccSum accSum = iter.next();
				if (null != accSum) {
					acc.sum += accSum.sum;
				}
			}
		}
	}
}
// 我瞎鼓捣实现的
import org.apache.flink.table.functions.AggregateFunction;

// 继承AggregateFunction类,
public class AggFTest01{
    public static class SKTest{
        public long sum1 = 0;
        public long sum2 = 0;
        public int count = 0;
    }
    public static class Test01 extends AggregateFunction<Long,SKTest>{


        /**
         * 获取最终结果
         */
        @Override
        public Long getValue(SKTest skTest) {

            return skTest.sum2;
        }

        /**
         * 创建结果集对象
         */
        @Override
        public SKTest createAccumulator() {
            return new SKTest();
        }


        /**
         * 创建处理逻辑
         */
        public void accumulate(SKTest skTest, String value) {
            String[] arr1 = value.split("_");
            for (int i = 0; i < 2; i++) {
                if (i != 0){
                    skTest.sum2 = arr1[i].length();
                }
                else
                    skTest.sum1 = arr1[i].length();
            }
        }
    }
}

阿里云使用的话,明天上班再搞,摸鱼学习中,不能晚上加班。

UDSF类型实现

此类型主要是是一对一数据处理(聚合类型的udf引入其他字段的话,会出现非group by字段,仔细看了一下对应UDF解释实现此类型Demo)

CREATE TEMPORARY TABLE datagen_source1 (
 k1 STRING NOT NULL
) WITH (
 'connector' = 'datagen',
 'fields.k1.length' = '10'
);

CREATE TEMPORARY TABLE datagen_source2 (
 v1 STRING NOT NULL
) WITH (
 'connector' = 'datagen',
 'fields.v1.length' = '10'
);


CREATE TEMPORARY TABLE mid_table(
  con_str BIGINT
) WITH (
  'connector' = 'print'
);

CREATE TEMPORARY FUNCTION `mysum1` AS 'CreateKafkaData.UDSFDemo';

SELECT 
  `mysum1`(datagen_source1.k1,datagen_source2.v1)
  ,datagen_source1.k1
  ,datagen_source2.v1
FROM 
datagen_source1
inner join
datagen_source2
on 1=1;


在这里插入图片描述

在这里插入图片描述

阿里云 VVP使用

(可以理解为VVP是Flink的运载Web UI,同时提供了大量的辅助组件,阿里云VVP你值得拥有)
maven建Java项目就不细讲了,需要的话,自行百度哈
在这里插入图片描述
首先,你得有阿里云flink实时计算平台哈,哈哈哈哈,问题不大,现在好像新用户都可以试用,有需要的可以去瞅瞅嘞。

附件形式传输

自定义UDF有两种,此处是临时使用,也可设置全局使用
在这里插入图片描述

CREATE TEMPORARY TABLE ASI_UDAF_Source (
  a   BIGINT NOT NULL
) WITH (
  'connector' = 'datagen'
);

CREATE TEMPORARY TABLE ASI_UDAF_Sink (
  `sum`  BIGINT
) WITH (
  'connector' = 'print'
);
/**
* 路径要写到继承AggregateFunction类为止
* 内部类调用  类名$内部类名
* 通常都是 package.类名$内部类名
*/
CREATE TEMPORARY FUNCTION `mysum` AS 'ASI_UDAF$MySum';
CREATE TEMPORARY FUNCTION `mysum1` AS 'AggFTest01$Test01';

SELECT `mysum`(a)
FROM ASI_UDAF_Source;

点调试哈,这项目要上线,top会把我开除的
在这里插入图片描述
官方给的示例过了,我自己写的也要安排一下
预期实现逻辑:拼接字符串,但约束字符串长度,输出最后字符串截取的大小。
代码实现的初步逻辑是,a_b ,看看a和b的字段长度

后来约束了二者的长度都是固定10,然后也没判断长度,分割后,固定大小都是10
flink后台直接把我任务停了,估计是不允许那种条件常为定值的作业。

CREATE TEMPORARY TABLE datagen_source1 (
 k1 STRING NOT NULL,
 v1 STRING NOT NULL
) WITH (
 'connector' = 'datagen',
 'fields.k1.length' = '10',
 'fields.v1.length' = '10'
);

CREATE TEMPORARY TABLE mid_table(
  con_str BIGINT
) WITH (
  'connector' = 'print'
);

-- RPAD(VARCHAR str, INT len, VARCHAR pad) 如果str不满足len长度,填充pad
CREATE TEMPORARY FUNCTION `mysum1` AS 'AggFTest01$Test01';

BEGIN STATEMENT SET;
INSERT INTO mid_table
SELECT `mysum1`(t1.v2)
FROM 
(select
  CONCAT(k1,'_',v1) as v2
from
  datagen_source1) t1
;
END;

资源上传方式

具体的内容,官网应该很清晰了,这个小标题下,会汇总一些用户使用出现的小问题
算是自己的学习小汇总嘞
VVP上传UDF(官方)
点击对应函数,可直接使用对应函数
在这里插入图片描述

自定义命名后报错jar存在

VVP平台上传的JAR名称也具有唯一性,可理解为UDF名称,JAR名称不是联合主键。
在这里插入图片描述

补充

1、UDF里面增加了日志逻辑,控制台没有日志输出
解决办法:
在这里插入图片描述
2、多输入
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值