Flink 是一个流处理和批处理统一的大数据框架,专门为高吞吐量和低延迟而设计。开发者可以使用SQL进行流批统一处理,大大简化了数据处理的复杂性。本文将介绍Flink SQL的基本原理、使用方法、流批统一,并通过几个例子进行实践。

1、Flink SQL基本原理

Flink SQL建立在Apache Flink之上,利用Flink的强大处理能力,使得用户可以使用SQL语句进行流数据和批数据处理。Flink SQL既支持实时的流数据处理,也支持有界的批数据处理。

Flink SQL用SQL作为处理数据的接口语言,将SQL语句转换成数据流图(Dataflow Graph),再由Flink引擎执行。

2、Flink SQL固定编码套路

使用Flink SQL时,我们通常会遵循如下编码套路,这些套路和使用Flink API的套路是一样的:

  • 环境准备:初始化一个TableEnvironment对象,它是执行Flink SQL语句的核心。这个环境可以是流数据环境,也可以是批数据环境。
  • 数据源定义:通过CREATE TABLE语句定义输入数据源(source),可以是Kafka、CSV文件等。
  • 数据处理:编写SQL语句对数据进行处理,如查询、过滤、聚合等。
  • 数据输出:通过CREATE TABLE定义输出数据源(sink),并将处理结果输出。

3、Flink SQL代码示例

以下是一个从CSV文件读取数据,通过SQL查询,再将数据输出到CSV的完整例子。

  • 先准备input.csv文件内容,如下:
1,product_A,10.5
2,product_B,20.3
3,product_C,15.8
1,product_D,12.2
2,product_A,18.7
  • 编写demo代码

编写代码之前先在pom.xml中添加依赖:

<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-csv</artifactId>
<version>${flink.version}</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-json</artifactId>
<version>${flink.version}</version>
</dependency>

示例代码如下:

import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.EnvironmentSettings;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment; public class FlinkSqlDemo {
public static void main(String[] args) throws Exception {
// 设置环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(1); //为了方便测试看效果,这里并行度设置为1
// 使用EnvironmentSettings创建StreamTableEnvironment,明确设置为批处理模式
EnvironmentSettings settings = EnvironmentSettings
.newInstance()
.inBatchMode() // 设置为批处理模式,这样后续才能一次性的输出到csv中
.build();
StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env, settings); // 定义输入数据源
String createSourceTableDdl = "CREATE TABLE csv_source (" +
" user_id INT," +
" product STRING," +
" order_amount DOUBLE" +
") WITH (" +
" 'connector' = 'filesystem'," +
" 'path' = 'file:///path/input.csv'," +
" 'format' = 'csv'" +
")";
tableEnv.executeSql(createSourceTableDdl); // // 编写 SQL 查询
// String query = "SELECT user_id, SUM(order_amount) AS total_amount FROM csv_source GROUP BY user_id";
// // 执行查询并打印
// tableEnv.executeSql(query).print();
// env.execute("Flink SQL Demo"); // 定义输出数据源
String createSinkTableDdl = "CREATE TABLE csv_sink (" +
" user_id INT," +
" total_amount DOUBLE" +
") WITH (" +
" 'connector' = 'filesystem'," +
" 'path' = 'file:///path/output.csv'," +
" 'format' = 'csv'" +
")";
tableEnv.executeSql(createSinkTableDdl); // 执行查询并将结果输出到csv_sink
String query = "INSERT INTO csv_sink " +
"SELECT user_id, SUM(order_amount) as total_amount " +
"FROM csv_source " +
"GROUP BY user_id";
tableEnv.executeSql(query);
// env.execute("Flink SQL Job");
}
}
  • 执行结果如下:

4、Flink SQL做流批统一

什么是流批统一?

流批统一是大数据处理领域的一个概念,它指的是使用一套代码来同时处理流数据(Streaming)和批数据(Batching)。

流处理和批处理的区别如下:

  1. 批处理(Batch Processing):

    • 批处理是指在某一时间点处理大量数据的手段。
    • 它通常涉及到对大量静止的(不再变化的)数据集进行一次性的处理。
    • 批处理作业通常在数据集完整可用后开始执行,并且经常是在数据仓库中进行。
    • 例如,一个电商平台可能在一天结束时运行一个批处理作业来处理当天所有的交易记录。
  2. 流处理(Stream Processing):
    • 流处理是指对数据实时进行处理,通常是数据生成或接收的同时立即进行。
    • 流处理适用于连续的数据输入,这些数据一直在变化,需要立即响应。
    • 例如,社交媒体平台在接收到新的帖子时,可能会实时分析这些帖子的内容和流行趋势。

在早期,流处理和批处理通常需要不同的系统来执行。对于批处理,可能使用如Hadoop这样的框架;而对于流处理,可能使用如Apache Storm这样的框架。这就导致开发者要同时学习多种框架才能处理不同类型的数据作业。

流批统一的概念,就是将这两种数据处理方式合并到一个平台中,这样一个系统既可以处理静止的大批量数据集,也可以处理实时的数据流。这样做的优点是显而易见的:

  • 统一的API:开发人员只需要学习和使用一套工具和API,可以共享更多的代码和逻辑。
  • 维护简便:只需维护一个系统,可以减少学习成本,减轻运维压力,减少故障点。
  • 灵活的数据处理:可以根据不同的业务需求灵活选择数据处理方式。

Flink SQL流批一体的实现原理

Flink很好的实现了流批统一,可以让开发人员用相同的方式来编写批处理和流处理程序。不论是对有界(批处理)还是无界(流处理)的数据源,Flink都可以使用相同的API和处理逻辑来处理数据。

Flink 通过内置的表抽象来实现流批一体,这里的"表"可以是动态变化的(例如,来自实时数据流的表)或是静态的(例如,存储在文件或数据库中的批量数据表)。Flink SQL引擎会根据数据的实际来源自动优化执行计划。

Flink SQL的流批统一核心在于三点:

  • 统一的API和SQL语义:Flink SQL提供一致的查询构建块(如窗口、时间处理函数),这些在流处理和批处理中语义一致,确保不同模式下行为的统一性。
  • 透明的状态处理:无论是流处理还是批处理,Flink都能够保持和恢复状态,为开发者提供一致的高容错性体验。
  • 多模态存储和处理能力:Flink SQL能够访问不同存储介质的数据,这意味着相同的SQL语句可以无缝在流数据和存储的批量数据上执行。

Flink SQL流批统一的代码示例

以下是一个完整的代码示例,用Flink来实现流批统一处理。Flink同时从Kafka 和 CSV读取数据,然后合并查询再输出结果:

  • 代码示例

代码中,先配置了Flink的流处理环境和表环境,然后用DDL语句在Flink中注册了Kafka和文件系统数据源。接着执行了一个SQL查询来合并来自这两种数据源的数据,并计算总金额。最后,打印出查询结果并开始执行Flink作业。

import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.EnvironmentSettings;
import org.apache.flink.table.api.Table;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;
import org.apache.flink.types.Row; public class StreamBatchUnifiedDemo {
public static void main(String[] args) throws Exception {
// 设置流处理的环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
EnvironmentSettings settings = EnvironmentSettings.newInstance()
.inStreamingMode()
.build();
StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env, settings); // Kafka 流处理表
String createKafkaSourceDDL = "CREATE TABLE kafka_stream_orders (" +
"order_id STRING," +
"amount DOUBLE)" +
"WITH (" +
"'connector' = 'kafka'," +
"'topic' = 'topic_test'," +
"'properties.bootstrap.servers' = '10.20.1.26:9092'," +
"'format' = 'json'," +
"'scan.startup.mode' = 'latest-offset'" +
")";
tableEnv.executeSql(createKafkaSourceDDL); // 文件系统批处理表
String createFilesystemSourceDDL = "CREATE TABLE file_batch_orders (" +
"order_id STRING," +
"amount DOUBLE)" +
"WITH (" +
"'connector' = 'filesystem'," +
"'path' = 'file:///Users/yclxiao/Project/bigdata/flink-blog/doc/input_order.csv'," +
"'format' = 'csv'" +
")";
tableEnv.executeSql(createFilesystemSourceDDL); // 执行统一查询,计算总金额
Table resultTable = tableEnv.sqlQuery("SELECT SUM(amount) FROM (" +
"SELECT amount FROM kafka_stream_orders " +
"UNION ALL " +
"SELECT amount FROM file_batch_orders)"); // 打印结果
tableEnv.toRetractStream(resultTable, Row.class).print(); // 开始执行程序
env.execute("Stream-Batch Unified Job");
}
}
  • 执行效果

通过以上示例代码,可以看出Flink SQL的流批一体设计:相同的SQL语句可以用在流处理和批处理中,而不需要做任何修改。Flink背后的执行引擎会自动根据数据的特性(流或者批)来进行相应的优化执行。

这就是Flink SQL非常强大的地方,它减少了开发者需要写不同代码逻辑的需求,简化了复杂的数据处理流程。

5、总结

Flink SQL是一个非常强大的数据处理工具,可以应对多种复杂的数据处理场景。

本文主要介绍了Flink SQL的基本原理、编码套路、流批统一,再结合正确的代码示例进行实践。希望对你有帮助。

完整代码地址:https://github.com/yclxiao/flink-blog

======>>>>>> 关于我 <<<<<<======

本篇完结!欢迎点赞 关注 收藏!!!

原文链接:https://mp.weixin.qq.com/s/WqyCjiIMK49T6eDl_Upc1A

10分钟了解Flink SQL使用的更多相关文章

  1. Flink SQL结合Kafka、Elasticsearch、Kibana实时分析电商用户行为

    body { margin: 0 auto; font: 13px / 1 Helvetica, Arial, sans-serif; color: rgba(68, 68, 68, 1); padd ...

  2. Flink系列之1.10版流式SQL应用

    随着Flink 1.10的发布,对SQL的支持也非常强大.Flink 还提供了 MySql, Hive,ES, Kafka等连接器Connector,所以使用起来非常方便. 接下来咱们针对构建流式SQ ...

  3. [转帖]SQL Server 10分钟理解游标

    SQL Server 10分钟理解游标 https://www.cnblogs.com/VicLiu/p/11671776.html 概述 游标是邪恶的! 在关系数据库中,我们对于查询的思考是面向集合 ...

  4. sql server 以10分钟分组 统计人数

    请问针对时间段从每天早上7点开始统计每十分钟人 解决思路: 我以前做过一个关于月份的,是说每3个月以分组,其实是一样的.不过可能啊,整体数据量大会有问题.如果你只是求一天的,那绝对没问题.[1]如果只 ...

  5. sql server:取当前时间前10分钟之内的数据 dateadd()

    当前时间 select GETDATE() 当前时间点前10分钟 dateadd() ,GETDATE()) 取当前时间点前10分钟以内的数据,且按创建时间倒序排 select * from tabl ...

  6. 简单的SQl时间序列生成,每次时间间隔10分钟。

    create table #timeseries(Times datetime not null) go declare @firstdate datetime , @lastdate datetim ...

  7. Apache Flink SQL

    本篇核心目标是让大家概要了解一个完整的 Apache Flink SQL Job 的组成部分,以及 Apache Flink SQL 所提供的核心算子的语义,最后会应用 TumbleWindow 编写 ...

  8. Demo:基于 Flink SQL 构建流式应用

    Flink 1.10.0 于近期刚发布,释放了许多令人激动的新特性.尤其是 Flink SQL 模块,发展速度非常快,因此本文特意从实践的角度出发,带领大家一起探索使用 Flink SQL 如何快速构 ...

  9. Flink SQL Client综合实战

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  10. Flink SQL 核心概念剖析与编程案例实战

    本次,我们从 0 开始逐步剖析 Flink SQL 的来龙去脉以及核心概念,并附带完整的示例程序,希望对大家有帮助! 本文大纲 一.快速体验 Flink SQL 为了快速搭建环境体验 Flink SQ ...

随机推荐

  1. #树状数组#洛谷 5677 [GZOI2017]配对统计

    题目 分析 考虑处理出所有右端点的能够匹配的左端点,然后用树状数组离线查询 代码 #include <cstdio> #include <cctype> #include &l ...

  2. 在DAYU200上实现OpenHarmony跳转拨号界面

    一.简介 日常生活中,打电话是最常见的交流方式之一,那么如何在OpenAtom OpenHarmony(简称"OpenHarmony")中进行电话服务相关的开发呢?今天我们可以一起 ...

  3. C++ 开发者必读经典书籍推荐

    如果你正在学习C++,那么一本好的教材或参考书可以事半功倍.以下是几本我个人推荐的C++书籍或视频 C++基础 看书 C++ Primer C++程序设计语言 Effective C++ More E ...

  4. RabbitMQ 06 工作队列模式

    工作队列模式结构图: 这种模式非常适合多个工人等待任务到来的场景.任务有多个,一个一个丢进消息队列,工人也有很多个,就可以将这些任务分配个各个工人,让他们各自负责一些任务,并且做的快的工人还可以多完成 ...

  5. 比nestjs更优雅的ts控制反转策略-依赖查找

    一.Cabloy5.0内测预告 Cabloy5.0采用TS对整个全栈框架进行了脱胎换骨般的大重构,并且提供了更加优雅的ts控制反转策略,让我们的业务开发更加快捷顺畅 1. 新旧技术栈对比: 后端 前端 ...

  6. C#的AOP(最经典实现)

    (适用于.NET/.NET Core/.NET Framework) [目录]0.前言1.第一个AOP程序2.Aspect横切面编程3.一个横切面程序拦截多个主程序4.多个横切面程序拦截一个主程序5. ...

  7. c# 属性类(特性)

    前言 c# 属性类也称做特性.这是一篇垫文,为后面的过滤器和其他特性类的东西做铺垫. 正文 看一段代码: static void Main(string[] args) { Attribitefunc ...

  8. iOS企业证书开发的APP证书过期时间监控

    大家都知道iOS的企业证书开发的APP,证书都是一年有效期,满一年得新建证书重新打包,否则无法继续使用. 我们一个企业账号下有几十个APP,一个个去看也很麻烦--搞个监控呗!!! 写个脚本放Jenki ...

  9. 深度解读《深度探索C++对象模型》之数据成员的存取效率分析(一)

    接下来我将持续更新"深度解读<深度探索C++对象模型>"系列,敬请期待,欢迎关注!也可以关注公众号:iShare爱分享,自动获得推文和全部的文章列表. 在<深度解 ...

  10. 使用python获取知乎**话题下的所有回答,并统计后发布。

    第一步:获取话题需要的url需要,并向上取整 for idx in range(0,math.ceil(totals/5)): url = f"https://www.zhihu.com/a ...