当前位置: 首页 > news >正文

Flink编程模型与API(一)

针对Flink的编程模型与API进行讲解,主要基于DataStream API 进行编程,学习Flink编程方式,处理数据流程以及转换处理,本章节中涉及到的代码实现使用Java和Scala两种语言来实现。

Flink API

Stateful Stream Processing
底层的状态流处理API的抽象程度最低,而且只能用于流处理,提供了非常灵活的接口,可以用于自定义底层与状态、时间相关的操作。

DataSteam/DataSet API
这一层级的API是Flink中的核心API,这一层级中要处理的数据会被抽象成数据流(DataStream)或数据集(DataSet),然后在其上通过定义转换操作实现业务逻辑,例如:map/flatMap/window/keyby/sum/join等,这一层级API的使用风格与Java 8中的Stream使用风格十分类似。

Table API
在DataStream/DataSet API 之上是Table API ,Table API和DataStream/DataSet API不同,不是用复杂的函数定义业务流程的,而是用陈述性的语言加以描述,这样就大大降低编程难度,增强描述性。这种语言来着SQL语法,只不过以API的形式呈现出来,既然有了Table API ,那么自然可以直接使用SQL来进行描述,这就是最上层的SQL。

SQL
Flink提供的最高层级的抽象是SQL,这一层抽象在语法与表达能力上与Table API 类似,SQL抽象与Table API交互密切,同时SQL查询可以直接在Table API定义的表上执行。

总而言之,越上层的API,其描述性和可阅读性越强,越下层API,其灵活度高、表达力越强,多数时候上层API能做到的事情,下层API也能做到,反过来未必,不过这些API的底层模型是一致的,可以混合使用。

Flink架构可以处理批和流,Flink 批处理数据需要使用到Flink中的DataSet API,此API主要是支持Flink针对批数据进行操作,本质上Flink处理批数据也是看成一种特殊的流处理(有界流),所以没有必要分成批和流两套API,从Flink1.12版本往后,Dataset API 已经标记为Legacy(已过时),已被官方软弃用,官方建议使用Table API 或者SQL 来处理批数据,我们也可以使用带有Batch执行模式的DataStream API来处理批数据(DataSet和DataStream API做到了合并),在未来Flink版本中DataSet API 将会被删除。

DataStream API的学习对于理解Flink数据处理流程非常方便,上手相对来说比较容易,下面我们先从核心API层开始学习,对于底层API、Table API、SQL部分在后续章节在做介绍。

Flink编程模型

代码编写流程

我们知道DataStream的编程模型包括以下几个部分:Environment、DataSource、Transformation、DataSink、触发执行。

nvironment是编写Flink程序的基础,不同层级API编程中创建的Environment环境不同,如:Dataset 编程中需要创建ExecutionEnvironment,DataStream编程中需要创建StreamExecutionEnvironment,在Table和SQL API中需要创建TableExecutionEnvironment,使用不同语言编程导入的包也不同,在获取到对应的Environment后我们还可以进行外参数的配置,例如:并行度、容错机制设置等。

DataSource部分主要定义了数据接入功能,主要是将外部数据接入到Flink系统中并转换成DataStream对象供后续的转换使用。Transformation部分有各种各样的算子操作可以对DataStream流进行转换操作,最终将转换结果数据通过DataSink写出到外部存储介质中,例如:文件、数据库、Kafka消息系统等。

在DataStream编程中编写完成DataSink代码后并不意味着程序结束,由于Flink是基于事件驱动处理的,有一条数据时就会进行处理,所以最后一定要使用Environment.execute()来触发程序执行。

Flink数据类型

在Flink内部处理数据时,涉及到数据的网络传输、数据的序列化及反序列化,Flink需要知道操作的数据类型,为了能够在分布式计算过程中对数据的类型进行管理和判断,Flink中定义了TypeInformation来对数据类型进行描述,通过TypeInfomation能够在数据处理之前将数据类型推断出来,而不是真正在触发计算后才识别出,这样可以有效避免用户在编写Flink应用的过程出现数据类型问题。

常用的TypeInformation有BasicTypeInfo、TupleTypeInfo、CaseClassTypeInfo、PojoTypeInfo类等,针对这些常用TypeInfomation介绍如下:

Flink通过实现BasicTypeInfo数据类型,能够支持任意Java原生基本(或装箱)类型和String类型,例如:Integer,String,Double等,除了BasicTypeInfo外,类似的还有BasicArrayTypeInfo,支持Java中数组和集合类型;
通过定义TupleTypeInfo来支持Tuple类型的数据;
通过CaseClassTypeInfo支持Scala Case Class ;
PojoTypeInfo可以识别任意的POJOs类,包括Java和Scala类,POJOs可以完成复杂数据架构的定义,但是在Flink中使用POJOs数据类型需要满足以下要求:
POJOs类必须是Public修饰且独立定义,不能是内部类;
POJOs 类中必须含有默认空构造器;
POJOs类中所有的Fields必须是Public或者具有Public修饰的getter和Setter方法;
在使用Java API开发Flink应用时,通常情况下Flink都能正常进行数据类型推断进而选择合适的serializers以及comparators,但是在定义函数时如果使用到了泛型,JVM就会出现类型擦除的问题,Flink就获取不到对应的类型信息,这就需要借助类型提示(Type Hints)来告诉系统函数中传入的参数类型信息和输出类型,进而对数据类型进行推断处理。如:

Flink序列化机制

在两个进程进行远程通信时,它们需要将各种类型的数据以二进制序列的形式在网络上传输,数据发送方需要将对象转换为字节序列,进行序列化,而接收方则将字节序列恢复为各种对象,进行反序列化。对象的序列化有两个主要用途:一是将对象的字节序列永久保存到硬盘上,通常存放在文件中;二是在网络上传输对象的字节序列。序列化的好处包括减少数据在内存和硬盘中的占用空间,减少网络传输开销,精确推算内存使用情况,降低垃圾回收的频率。

Flink序列化机制负责在节点之间传输数据时对数据对象进行序列化和反序列化,确保数据的正确性和一致性。Flink提供了多种序列化器,包括Kryo、Avro和Java序列化器等,大多数情况下,用户不用担心flink的序列化框架,Flink会通过TypeInfomation在数据处理之前推断数据类型,进而使用对应的序列化器,例如:针对标准类型(int,double,long,string)直接由Flink自带的序列化器处理,其他类型默认会交给Kryo处理。但是对于Kryo仍然无法处理的类型,可以采取以下两种解决方案:

public class Student { public Integer id; public String name; public Integer age; public Student() { } public Student(Integer id, String name, Integer age) { this.id = id; this.name = name; this.age = age; } @Override public String toString() { return "Student{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; } } public class StudentSerializer extends Serializer { @Override public void write(Kryo kryo, Output output, Object o) { Student student = (Student) o; output.writeInt(student.id); output.writeString(student.name); output.writeInt(student.age); } @Override public Object read(Kryo kryo, Input input, Class aClass) { Student student = new Student(); student.id = input.readInt(); student.name = input.readString(); student.age = input.readInt(); return student; } }

http://www.zskr.cn/news/1436943.html

相关文章:

  • 从零构建工作流驱动型 Writer Agent
  • 前端职业发展:从初级到专家的成长路径
  • 企业级Gemini生物识别集成成熟度评估矩阵(含12项等保2.0/GB/T 35273-2020对标项),仅开放前200份下载权限
  • 贝叶斯公式
  • 戴森球计划终极工厂蓝图库:5000+免费设计让你轻松构建星际帝国
  • 2026浙江AI搜索优化服务商深度评测与选型指南 - 品牌报告
  • 深入瑞芯微RK3568 BSP:从Android.bp到u-boot.img,带你读懂原厂SDK的目录结构与编译产物
  • 合肥理工学校招生办电话号码是多少?官网最新发布! - 教育为先
  • windows11 C盘文件过大清理方法汇总
  • 基于 Harmony 6.0 应用的宠物寄养预约系统实现
  • 告别电源‘打嗝’:一个恒流电路如何根治RCC的间歇振荡难题?
  • Arduino Nano一体化扩展板设计:集成电源管理与多电机驱动实战
  • 2026南京卫生间漏水免砸砖维修 本地防水堵漏权威测评口碑优选商家 - 吉修匠
  • 用Arduino与WS2812B制作可编程圣诞灯光标志:从硬件到软件全流程
  • Windows 11终极优化指南:用Win11Debloat一键清理系统冗余,让电脑重获新生
  • 2026廊坊GEO优化服务商权威榜单TOP4|全域合规选型指南 - 余小铁
  • 2026无锡防水修缮权威测评 微创免砸砖堵漏高口碑榜单 - 吉修匠
  • 基于Matlab模拟海洋病原体传播建模附GUI界面
  • 2026苏州免砸砖防水上门维修 疑难渗水高效修复口碑权威榜单 - 吉修匠
  • 边缘计算中的高效LLM推理:FastTTS技术解析与实践
  • Arduino入门:从零实现LED闪烁,掌握嵌入式开发基础
  • 基于Arduino的智能电子骰子:从传感器到交互的嵌入式开发实践
  • Linux.do 社区热议:AI 公益站动态与生活百态
  • Arduino NeoPixel互动计分游戏机:从硬件设计到游戏逻辑实现
  • 从零设计集成化Arduino电机驱动PCB:L293D、ATmega328P与PCB布局实战
  • 多个pdf合并成一个的免费工具?2026免费PDF合并工具实测对比 - 科技大爆炸
  • 论文写作的开挂模式!智能AI写作辅助平台,成稿速度超迅速
  • 基于Arduino与HC-SR04的倒车雷达系统:从超声波测距到实时报警
  • 千问 LeetCode 2862. 完全子集的最大元素和 TypeScript实现
  • 2026西安正规老酒水回收陈年茅台品鉴馆同城极速上门服务高价回收 - 速递信息