kepler利用udtf将json多行输出

前言

接到了一个实时计算的需求,大致是一个流式计算,需要将DRC提取到的变更数据进行过滤与数据处理后落库。之前也没有接触过大数据,因此对阿里的kepler进行了学习,在此总结。

流式计算

在日常生活中,我们通常会先把数据存储在一张表中,然后再进行加工、分析,这里就涉及到一个时效性的问题。如果我们处理以年、月为单位的级别的数据,那么多数据的实时性要求并不高;但如果我们处理的是以天、小时,甚至分钟为单位的数据,那么对数据的时效性要求就比较高。在第二种场景下,如果我们仍旧采用传统的数据处理方式,统一收集数据,存储到数据库中,之后在进行分析,就可能无法满足时效性的要求。

Kepler 蚂蚁实时计算平台

img

DSL和OPERATOR层

Kepler为用户提供了SQL和高阶算子两种编程范式:

  • Kepler SQL:兼容了大部分的 Streaming SQL 的语义,并支持 Window、Trigger等 Apache Beam的概念。SQL由于易上手易维护的特点,是目前Kepler用户使用方式的主流。

  • 高阶算子:Kepler内置了完备的实时计算算子,包括:过滤(Filter)、转换(UDF、UDTF)、聚合(UDAF)、多流 Join、Union、Split 等类型,在 Spark 、Flink 高阶 API 里你能看到相同的概念,通过组装这些算子,用户可以轻松实现一个自定义逻辑的DataStream。通过高阶API,用户可以更细粒度地去描述计算本身,而因为高阶算子封装了 State、Retract 等能力,又为用户省去了繁琐的存储和出错回滚细节。

ENGINE层

Kepler底层执行引擎专注调度和执行数据流,而执行引擎对于算子层是可插拔的,目前Kepler支持了默认的执行引擎和蚂蚁的分布式计算框架 Raya。

IO模块

至于输入数据源和计算结果输出存储,Kepler 支持了蚂蚁所有的 Queue 系统和存储系统,包括但不限于SLS、AntQ、DRC、HBase、MySQL、Kudu、Pangu、Explorer 等等。并且这些存储类型都有对应的内置IO组件,用户不需要写任何 IO 相关的一行代码,就能轻松完成数据读取和存储。

具体实现

总体思路是根据内置的udtf进行改写
1、引入maven依赖
2、创建一个类继承UDF类,
3、写eval方法,规定传入的参数,框架会在运行时会根据参数的类型匹配对应的 eval 方法。
4、对数据进行处理后传入collect()方法。
5、对其中的getReturnType方法进行重写,输出的字段类型在 getReturnType 函数定义

代码示例

在这里,我实现的功能是将某个example字段多行输出,example是个jason数组的字符串,我需要提出字段中的每个jason的Name属性,并作为不同行的记录输出。

 [
 {"Name":"Apollo","School":{"Name":"Thu","City":"BeiJing"}}, 
 {"Name":"Apollo2","School":{"Name":"Thu2","City":"BeiJing2"}}
 ]

示例如下

		1,1,1,hello|java
******根据‘|’分割作为不同行输出*********
		1,1,1,hello
		1,1,1,java

实现代码


public class newsplit extends UDTF {
   
  //arg0为传入String,arg1为需要提取的字段如instanceName
    public void eval(String arg0, String arg1) {
        evalInternal(arg0, arg1);
    }
    
	//具体实现方法
	//传入目标字符串a,以及我要提取的属性名字b,及json的key
    private void evalInternal(String a, String b) {
        if (a != null) {
          	//将字符串a转为JSONArray,此时每个数组元素都是Object类型,无法直接得到jason的key
            JSONArray jsArr = JSONObject.parseArray(a);
            int len = jsArr.size();
            String[] strs = new String[len];
            //遍历数组每个Object对象
            for(int i = 0; i < len; i++){
            	//将Object先变成String类型,然后利用parseObject变成JSONObject,因为JSONObject只能String作为参数
                JSONObject obj = JSONObject.parseObject(jsArr.get(i).toString());
                //JSONObject可以直接get(key)方法得到预提取字符,储存进字符串数组strs
                strs[i] = obj.get(b).toString();
            }
			
			//具体输出,遍历str字符串并传入collect()
            for (String str : strs) {
                collect(new Object[]{str});
            }
        }
    }
	
	
    @Override
    public List<Class<?>> getReturnType(List<Class<?>> paramTypes,
                                        List<String> udtfReturnFields) {

        List<Class<?>> clazzs = Lists.newArrayList();
        clazzs.add(String.class);
        return clazzs;
    }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值