Apache Flink 是一个在无界和有界数据流上进行状态计算的框架和分布式处理引擎。Flink 已经可以在所有常见的集群环境中运行 (YARN/ Mesos/ Kubernetes),并以 in-memory 的速度和任意的规模进行计算。
Flink的用途:
由于Flink项目中很多华人开发者,因此有较多中文版的学习资料,但这些学子资料都是以由深到浅的方式介绍 Flink 的原理、概念,缺乏入门的demo,让初学者一头雾水。这一点上,Flink 的官方文档是不如 Spark 的官方文档的。
# Flink 1.8.0
# 安装目录 [192.168.102.85] home/devsa_dev/flink-1.8.0/
./bin/start-cluster.sh # 以StandAlone模式启动Flink集群
./bin/stop-cluster.sh # 启动Flink集群
./bin/flink --version # 查看Flink版本
./bin/flink run examples/streaming/WordCount.jar # 提交demo任务,WordCount
./bin/flink run -d examples/streaming/TopSpeedWindowing.jar # 提交demo任务,TopSpeedWindowing
./bin/sql-client.sh embedded # 启动Flink-SQL客户端
./bin/start-scala-shell.sh # 启动Flink的Scala shell入口
./bin/flink -h # 查看Flink的命令行参数
./bin/flink run -h # 查看run命令的参数
./bin/flink list -m 127.0.0.1:8081 # 查看任务列表
./bin/flink stop -m 127.0.0.1:8081 d67420e52bd051fae2fddbaa79e046bb # 停止任务
./bin/flink run -m yarn-cluster ./example/batch/WordCount.jar # 以yarn模式提交作业
Flink 的API可以使用 Java / Scala / Python 来调用。
Flink 最底层的API。它将通过过程函数(Process Function)嵌入到 DataStream API 中,允许用户可以自由地处理来自一个或多个流数据的事件,并使用一致、容错的状态。除此之外,用户可以注册事件时间和处理事件回调,从而使程序可以实现复杂的计算。
DataStream API 是 Flink API 中比较底层的一种,在实际的生产中,需要用户较大的开发工作量,但同时它也提供了更为灵活的表达能力,适用于需要精细操作的情况;而绝大多数业务逻辑,都可以用 Flink SQL 来实现。
Flink 提供的核心 API,DataSet 处理有界的数据集,DataStream 处理有界或者无界的数据流。用户可以通过各种方法(map / flatmap / window / keyby / sum / max / min / avg / join 等)将数据进行转换 / 计算。
Table API 与 Flink SQL 联系非常紧密。
Flink API 中最顶层的抽象,可以做流批统一处理。Flink SQL 是基于Apache Calcite来实现的标准SQL;它对于批(DataSet)和流(DataStream)的输入有相同的语义,也会产生同样的计算结果。它也是使用起来最简单的 API。
Table API 是以 表 为中心的声明式 DSL,其中表可能会动态变化(在表达流数据时)。Table API 提供了例如 select、project、join、group-by、aggregate 等操作,使用起来却更加简洁(代码量更少)。你可以在表与 DataStream/DataSet 之间无缝切换,也允许程序将 Table API 与 DataStream 以及 DataSet 混合使用。
Flink 提供的最高层级的抽象是 SQL 。这一层抽象在语法与表达能力上与 Table API 类似,但是是以 SQL查询表达式的形式表现程序。SQL 抽象与 Table API 交互密切,同时 SQL 查询可以直接在 Table API 定义的表上执行。
Flink SQL 使用类似 ANSI-SQL 的语言,操作流式数据,从而实现业务逻辑的实时计算;其本质是调用了封装在 Table API & SQL 中的 Flink 函数,也是 Flink API 中最高级、最简单的形式。通过简单的 SQL 语言就可以实现实时计算,从而实现业务与技术的解耦,这是 Flink 比 Spark Streaming 高明的地方。但是,Flink SQL 并不适用于过于复杂的业务逻辑的实现。
# Flink中常见的窗口函数
select -- 统计每五分钟、每个城市的骑车人数
city
, tumble_end(start_time, interval '5' minute) window_end -- 时间窗口,每5分钟统计一次
, count(*) cnt
from t_ride
WHERE is_del = 0
group by city
, tumble(start_time, interal '5' minute)
having count(*) >= 5
;
insert into sink_kafka_TenMinPsgCnts -- 将结果写入Kafka
select
tumble_start(ride_time, interval '10' minutes) cnt_start -- 每10分钟的搭乘的乘客数
, tumble_end(ride_time, interval '10' minutes) cnt_end
, cast(sum(psgCnt) as bigint) cnt
from t_rides
group by tumble(ride_time, interval '10' minutes)
;
-- 将结果写入Elasticsearch
insert into sink_elasticsearch_AreaCnts
select
city -- 每个区域出发的行车数
, count(*) cnt
from t_rides
where is_del = 0
group by city
;
< !-- Flink Table API的依赖 -- >
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-api-java-bridge_2.11</artifactId>
<version>1.11.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-scala_2.11</artifactId>
<version>1.11.0</version>
<scope>provided</scope>
</dependency>
< !-- Flink Table API在本地IDE运行的依赖 -- >
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-planner-blink_2.11</artifactId>
<version>1.11.0</version>
<scope>provided</scope>
</dependency>
Flink 的这不分 API 操作与 Spark Streaming有非常多的相似之处。