做为一家创新驱动的科技公司,袋鼠云每一年研发投入达数千万,公司80%员工都是技术人员,袋鼠云产品家族包括企业级一站式数据中台PaaS数栈、交互式数据可视化大屏开发平台Easy[V]等产品也在迅速迭代。在进行产品研发的过程当中,技术小哥哥们能文能武,不断提高产品性能和体验的同时,也把这些提高和优化过程记录下来,现录入“袋鼠云研发手记”专栏中,以和业内童鞋们分享交流。java
下为“袋鼠云研发手记”专栏第三期,本期做者为袋鼠云数栈引擎团队。mysql
袋鼠云数栈引擎团队redis
袋鼠云数栈引擎团队拥有多名专家级别,经验丰富的后端开发工程师,分别支撑公司大数栈产品线的不一样子项目的开发需求,从项目中提取并开源了FlinkX(基于Flink的数据同步),Jlogstash(logstash 的java 版本实现),FlinkStreamSQL(扩展原生FlinkSQL,实现流与维表的join)多个项目。sql
在长期的项目实践与产品迭代过程当中,团队成员在 Hadoop技术栈上不断深耕探索,积累了丰富的经验与最佳实践。数据库
第三期后端
数栈·开源 拓展FlinkSQL实现流与维表的joinapi
FlinkStreamSQL 已经开源在Github上 目前已获380+Star缓存
一、为何要扩展FlinkSQL?网络
实时计算须要彻底SQL化oracle
SQL是数据处理中使用最普遍的语言。它容许用户简明扼要地声明他们的业务逻辑。大数据批计算使用SQL很常见,可是支持SQL的实时计算并很少。其实,用SQL开发实时任务能够极大下降数据开发的门槛,在袋鼠云数栈-实时计算模块,咱们决定实现彻底SQL化。
数据计算采用SQL的优点
☑ 声明式。用户只须要表达我想要什么,至于怎么计算那是系统的事情,用户不用关心。
☑ 自动调优。查询优化器能够为用户的 SQL 生成最有的执行计划。用户不须要了解它,就能自动享受优化器带来的性能提高。
☑ 易于理解。不少不一样行业不一样领域的人都懂 SQL,SQL 的学习门槛很低,用 SQL 做为跨团队的开发语言能够很大地提升效率。
☑ 稳定。SQL 是一个拥有几十年历史的语言,是一个很是稳定的语言,不多有变更。因此当咱们升级引擎的版本时,甚至替换成另外一个引擎,均可以作到兼容地、平滑地升级。
实时计算还须要流与维表的JOIN
在实时计算的世界里不仅是流与流的JOIN,还须要流与维表的JOIN
在实时计算的世界里不仅是流与流的JOIN,还须要流与维表的JOIN。在去年,袋鼠云数栈V3.0版本研发期间,当时最新版本——flink1.6中FlinkSQL,已经将SQL的优点应用到Flink引擎中,但还未支持流与维表的JOIN。
关于FlinkSQL
FlinkSQL于2017年7月开始面向阿里巴巴集团开放流计算服务的,虽然是一个很是年轻的产品,可是到双11期间已经支撑了数千个做业,在双11期间,Blink 做业的处理峰值达到了5+亿每秒,而其中仅 Flink SQL 做业的处理总峰值就达到了3亿/秒。
参考连接:https://yq.aliyun.com/article...
这里先解释下什么是维表;维表是动态表,表里所存储的数据有可能不变,也有可能定时更新,可是更新频率不是很频繁。在业务开发中通常的维表数据存储在关系型数据库如mysql,oracle等,也可能存储在hbase,redis等nosql数据库。
二、因此要用FlinkSQL实现流与维表的join 分两步:
1、用Flink api实现维表的功能
要实现维表功能就要用到 Flink Aysnc I/O 这个功能,是由阿里巴巴贡献给Apache Flink的。
Async I/O 是由阿里巴巴贡献给社区的,于1.2版本引入,主要目的是为了解决与外部系统交互时网络延迟成为了系统瓶颈的问题。具体介绍能够看这篇文章:http://wuchong.me/blog/2017/0...
对应到Flink 的api就是RichAsyncFunction 这个抽象类,继层这个抽象类实现里面的open(初始化),asyncInvoke(数据异步调用),close(中止的一些操做)方法,最主要的是实现asyncInvoke 里面的方法。
流与维表的join会碰到两个问题:
第一个是性能问题。由于流速要是很快,每一条数据都须要到维表作下join,可是维表的数据是存在第三方存储系统,若是实时访问第三方存储系统,不只join的性能会差,每次都要走网络io;还会给第三方存储系统带来很大的压力,有可能会把第三方存储系统搞挂掉。
因此解决的方法就是维表里的数据要缓存,能够全量缓存,这个主要是维表数据不大的状况,还有一个是LRU缓存,维表数据量比较大的状况。
LRU维表的实现
第二个问题是流延迟过来的数据这么跟以前的维表数据作关联。这个就涉及到维表数据须要存储快照数据,因此这样的场景用HBase 作维表是比较适合的,由于HBase 是天生支持数据多版本的。
ALL维表的实现
2、解析流与维表join的SQL语法转化成底层的FlinkAPI
由于FlinkSQL已经作了大部分SQL场景,咱们不可能在去解析SQL的全部语法,在把他转化成底层FlinkAPI。
因此咱们作的就是解析SQL语法,来找到join表里有没有维表,若是有维表,那咱们会把这个join的维表的语句单独拆来,用Flink的TableAPI和StreamAPi 生成新DataStream,在把这个DataStream与其余的表在作join这样就能用SQL来实现流与维表的join语法了。
SQL解析的工具就是用Apache calcite,Flink也是用这个框架作SQL解析的。因此全部语法都是能够解析的。
1. DEMO SQL
3. Calcite继续解析select语句
Calcite继续解析select语句
Calcite继续解析select语句