2019年1月28日,阿里云宣布开源“计算王牌”实时计算平台Blink回馈给ApacheFlink社区。官方称,计算延迟已经降到毫秒级,也就是你在浏览网页的时候,眨了一下眼睛,淘宝、天猫处理的信息已经刷新了17亿次。

作为一家对技术有追求、有渴望的公司,怎么少得了为Flink社区做些贡献呢?

夫子说

首先,本文所述均基于flink 1.5.4。

我们为什么扩展Flink-SQL?

由于Flink 本身SQL语法并不提供在对接输入源和输出目的的SQL语法。数据开发在使用的过程中需要根据其提供的Api接口编写Source和 Sink, 异常繁琐,不仅需要了解FLink 各类Operator的API,还需要对各个组件的相关调用方式有了解(比如kafka,redis,mongo,hbase等),并且在需要关联到外部数据源的时候没有提供SQL相关的实现方式,因此数据开发直接使用Flink编写SQL作为实时的数据分析时需要较大的额外工作量。

我们的目的是在使用Flink-SQL的时候只需要关心做什么,而不需要关心怎么做。不需要过多的关心程序的实现,专注于业务逻辑。

接下来,我们一起来看下Flink-SQL的扩展实现吧!

01扩展了哪些flink相关sql

(1)创建源表语句

(2)创建输出表语句

(3)创建自定义函数

(4)维表关联

02各个模块是如何翻译到flink的实现

( 1 ) 如何将创建源表的sql语句转换为flink的operator;

Flink中表的都会映射到Table这个类。然后调用注册方法将Table注册到environment。

StreamTableEnvironment.registerTable(tableName, table);

当前我们只支持kafka数据源。Flink本身有读取kafka 的实现类, FlinkKafkaConsumer09,所以只需要根据指定参数实例化出该对象。并调用注册方法注册即可。

另外需要注意在flink sql经常会需要用到rowtime, proctime, 所以我们在注册表结构的时候额外添加rowtime,proctime。

当需要用到rowtime的使用需要额外指定DataStream.watermarks(assignTimestampsAndWatermarks),自定义watermark主要做两个事情:1:如何从Row中获取时间字段。 2:设定最大延迟时间。

( 2 ) 如何将创建的输出表sql语句转换为flink的operator;

Flink输出Operator的基类是OutputFormat, 我们这里继承的是RichOutputFormat, 该抽象类继承OutputFormat,额外实现了获取运行环境的方法getRuntimeContext(), 方便于我们之后自定义metric等操作。

我们以输出到mysql插件mysql-sink为例,分两部分:

  • 将create table 解析出表名称,字段信息,mysql连接信息。

该部分使用正则表达式的方式将create table 语句转换为内部的一个实现类。该类存储了表名称,字段信息,插件类型,插件连接信息。

  • 继承RichOutputFormat将数据写到对应的外部数据源。

主要是实现writeRecord方法,在mysql插件中其实就是调用jdbc 实现插入或者更新方法。

( 3) 如何将自定义函数语句转换为flink的operator;

Flink对udf提供两种类型的实现方式:

(1)继承ScalarFunction

(2)继承TableFunction

需要做的将用户提供的jar添加到URLClassLoader, 并加载指定的class (实现上述接口的类路径),然后调用TableEnvironment.registerFunction(funcName, udfFunc);即完成了udf的注册。之后即可使用改定义的udf;

( 4 ) 维表功能是如何实现的?

流计算中一个常见的需求就是为数据流补齐字段。因为数据采集端采集到的数据往往比较有限,在做数据分析之前,就要先将所需的维度信息补全,但是当前flink并未提供join外部数据源的SQL功能。

实现该功能需要注意的几个问题:

(1)维表的数据是不断变化的

在实现的时候需要支持定时更新内存中的缓存的外部数据源,比如使用LRU等策略。

(2)IO吞吐问题

如果每接收到一条数据就串行到外部数据源去获取对应的关联记录的话,网络延迟将会是系统最大的瓶颈。这里我们选择阿里贡献给flink社区的算子RichAsyncFunction。该算子使用异步的方式从外部数据源获取数据,大大减少了花费在网络请求上的时间。

(3)如何将sql 中包含的维表解析到flink operator

为了从sql中解析出指定的维表和过滤条件, 使用正则明显不是一个合适的办法。需要匹配各种可能性。将是一个无穷无尽的过程。查看flink本身对sql的解析。它使用了calcite做为sql解析的工作。将sql解析出一个语法树,通过迭代的方式,搜索到对应的维表;然后将维表和非维表结构分开。

通过上述步骤可以通过SQL完成常用的从kafka源表,join外部数据源,写入到指定的外部目的结构中。

技本功丨用短平快的方式告诉你:Flink-SQL的扩展实现的更多相关文章

  1. 技本功丨收藏!斜杠青年与你共探微信小程序云开发(下篇)

    2019年2月26日,人们为了一个杯子疯了一天. 星巴克猫爪杯,一场已经与猫无关了的“圣杯战争“.网上的倒卖价格,已炒至近千元! 求而不得,舍而不能,得而不惜.这是人最大的悲哀... 所以,请珍惜以下 ...

  2. 技本功丨知否知否,Redux源码竟如此意味深长(上集)

    夫 子 说 元月二号欠下袋鼠云技术公号一篇关于Redux源码解读的文章,转眼月底,期间常被“债主”上门催债.由于年底项目工期比较紧,于是债务就这样被利滚利.但是好在这段时间有点闲暇,于是赶紧把这篇文章 ...

  3. 技本功丨请带上纸笔刷着看:解读MySQL执行计划的type列和extra列

    本萌最近被一则新闻深受鼓舞,西工大硬核“女学神”白雨桐,获6所世界顶级大学博士录取 货真价值的才貌双全,别人家的孩子 高考失利与心仪的专业失之交臂,选择了软件工程这门自己完全不懂的专业.即便全部归零, ...

  4. 技本功丨利用 Atomic 构建 React 项目工作流,so easy!

    近日刷微博,#2018年结婚率创新低#荣登热门话题NO.1,沪浙最不积极. 生活压力越大,缺爱的人也越来越多...据本萌的不完全观察,程序猿虽然是压力加成的职业,在袋鼠云还是有不少早早脱了单.至于,脱 ...

  5. 技本功丨知否知否,Redux源码竟如此意味深长(下集)

    上集回顾 Redux是如何使用的?首先再来回顾一下这个使用demo(谁让这段代码完整地展示了redux的使用) 如果有小伙伴对这段代码不是很理解的话,建议先去学习Redux的使用再来看这篇源码,这样更 ...

  6. 【整理】Linux下中文检索引擎coreseek4安装,以及PHP使用sphinx的三种方式(sphinxapi,sphinx的php扩展,SphinxSe作为mysql存储引擎)

          一,软件准备 coreseek4.1 (包含coreseek测试版和mmseg最新版本,以及测试数据包[内置中文分词与搜索.单字切分.mysql数据源.python数据源.RT实时索引等测 ...

  7. mybat使用注解的方式如@Select写sql

    package com.polymer.app.mapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibati ...

  8. hint不当索引,影响多表连接方式,最终导致SQL执行缓慢

    需求:一个SQL执行特别慢,无法返回结果,需要进行优化,最终返回结果即可. 一.SQL分析 二.尝试执行,观测执行计划 三.修改SQL 四.问题总结 一.SQL分析 )SQL文本,执行时间,执行用户 ...

  9. 数据迁移最快方式,多线程并行执行 Sql插入

    前言: 由于系统升级,新开发的系统对数据验证,及数据关联做了很多优化,现需要将原历史版本的数据迁移到新系统中:原数据库大约有 1千多万数据,大约 50个表. 历史数据库命名为:A. 新系统库暂命名为 ...

随机推荐

  1. 字符型设备驱动程序-first-printf以及点亮LED灯(四)

    怎么样 把 写的 代码 和 编译 放到  开发板上 去执行? 2017年5月22日16:34:13 需要 自己 编译 Linux 内核.. 需要 以下 几个 条件: 1.正常运行 Linux 的 开发 ...

  2. i2c 通信

    时间长了记忆就会模糊, 保存下逻辑分析抓到的图像, 什么时候需要可以看一眼. 当clk处于高电平时, data线有下降,说明开始传输, 有上升说明结束传输. 发送地址无回应: 发送地址有回应 正常数据 ...

  3. 寻找最小的k个数(四种方法)

    1 使用从大到小的优先队列保存最小的K个数,每次取出K个数之后的其余数和堆顶元素比较,如果比堆顶元素小,则将堆顶元素删除,将该元素插入 void topK(int arr[],int n,int k) ...

  4. Java并发编程(二)创建线程的三种方法

    进程与线程 1.  进程 进程和代码之间的关系就像音乐和乐谱之间的关系一样,演奏结束的时候音乐就不存在了但乐谱还在:程序执行结束的时候进程就消失了但代码还在,而计算机就是代码的演奏家. 2. 线程 线 ...

  5. JAVA中基本类型和字符串之间的转换

    一.基本类型转换成字符串有三种方法: int c = 10; 1.使用包转类的toString()方法 String str1 = Integer.toString(c); 2.使用String类的v ...

  6. SQL中的CONVERT();cast()函数

    SQLSERVER中CONVERT函数格式: CAST (expression AS data_type) 参数说明: expression:任何有效的SQLServer表达式. AS:用于分隔两个参 ...

  7. 【六】tf和cgi进行联合试验,完成日志服务器

    [任务6]tf和cgi进行联合试验,完成日志服务器 [任务6]tf和cgi进行联合试验,完成日志服务器 改装gen-cpp目录下client.cpp文件 启动Nginx服务和gen-cpp目录下编译后 ...

  8. 使用aapt查看apk包名和启动的activity

    执行命令: aapt dump badging F:\知乎.apk

  9. golang 切片小记

    1 切片初始化 func printSlice(s []int) { fmt.Printf("len=%d cap=%d underlying array:%p, %v\n", l ...

  10. spark 例子groupByKey分组计算2

    spark 例子groupByKey分组计算2 例子描述: 大概意思为,统计用户使用app的次数排名 原始数据: 000041b232,张三,FC:1A:11:5C:58:34,F8:E7:1E:1E ...