3.Flink中重要API的使用

Flink的编程模型可以归结为,创建环境--》定义source---》transformation数据转换---》写sink---》调用execute()方法。此外还需要注意的是Flink数据类型,序列化,反序列化,异步IO编程

1.Flink的序列化和反序列化

Flink各节点的数据交互,节点和外部数据的交互都是以序列化后二进制的形式在网络上传输,所有就需要Flink有序列化和反序列化的机制,flink中默认的有kryo(读法:快欧),avro(读法:鸭否),Java序列化器,还可以自定义序列化器

  • **自定义序列化器:**继承kyro的Serializer类,实现对应的write和read方法,然后在主函数中调用registerTypeWithKryoSerializer方法注册自定义的序列化器

2.Flink的编程环境

flink中的编程环境一共有三种,分别是DataSet类型的ExecutionEnvironment,DataStream类型的StreamExecutionEnvironment,用于Table和Sql的TableExecutionEnvironment

Flink source有官方实现的如,KafkaSource,FileSource,SocketSource等,也有一些组件自己实现的如Starrocks和Dris,这些实现好的source直接按照对应文档操作就可以,还有一种是官方或是第三方组件没有实现,需要自己实现的,接下来介绍下常用的KafkaSource和自己定义Source的具体代码

  • KafkaSource: 利用KafkaSource的build方法把kafka的broke集群链接地址,订阅的topic,groupId,消费策略,反序列化格式这些都配置好,KafkaSource就定义好了
  • 自定义source: 自定义的Source大体上可以分为两类,一类是不带parallel的SourceFunction和RichSourceFunction只能有一个并行度,另一类是带parallel的ParallelSourceFunction和RichParallelSourceFunction,它们可以设置多并发度。
    • 实现方法上来说分为有无Rich,带Rich的类是用继承的方式,它会多一个open()这样要给周期方法,里面可以实现一些初始化和数据库链接的操作
  • Transformation常见算子 有,map,flatMap,filter,keyBy,reduce,union,connect,这些都是系统定义好的函数,
  • 自定义函数: MapFunction,FlatFunction,FilterFunction,ReduceFunction,可以通过实现对应的方法灵活的处理流数据,
  • 富函数类: RichMapFunction,RichFlatMapFunction,RichFilterFunction,processFunction 等,这些富函数类的特点是他们都带生命周期方法如,open(),close(),getRuntimeContext(),其中getRuntimeContext()可以拿到函数执行的并行度,任务名字,以及state状态
    • processFunction是功能非常丰富的函数,它除了有类似富函数的一些生命周期方法,它还有onTimer(),可以实现定时器的功能
  • 分区操作:
    分区是flink实现各个task之间不同并行度的一种手段,共有8中分区的策略
  • hash partitioner: 根据元素的hashcode值对下游的分区个数取模,得到具体分区值
  • shuffle partitioner: 把上游的数据随机的分配到下游分区中
  • reblance partitioner: 把上游数据平均轮询的方式分配到下游分区中
  • rescale partitioner: 它也是用轮询的方式把数据平均发送到下游,但是它只会在自己的这个taskmanager中的各个slot中分发,shuffle和reblance都是全局跨taskmanager的分发,他们这更加的消耗资源
  • broadcast partitioner: 它会把上游的广播数据全部发送到下游的每个TaskManager中,各个slot中的subtask需要用到广播数据的可以去本地下载
  • global partitioner: 把上游所有分区的数据往下游的一个分区里发送,只让一个分区处理当前的数据
  • forward partitioner: 一对一的把 上游数据分发到下游分区,如果上下游分区数不一致会报错
  • 自定义分区: 调用partitionCustom(),第一个参数实现Partitoner类中的partition方法,它决定每个元素该去往下游的哪个分区,第二个参数是选择哪个字段作为分区的字段

flink的sink官方和第三方也实现了很多,比如,KafkaSink,FileSink,JdbcSink,下面介绍下JDBCSink和KafkaSink实现Exactly-once语义和自定义Sink

  • JDBCSink实现Exactly-once: 它是通过XA的这个标准规范来实现的,XA是一种分布式事务规范,它采用的是两阶段提交方式来管理分布式事务
    • 通过JdbcSink类的exactlyOnceSink方法实现,然后根据源码填写对应参数,其中需要注意的是在填写JdbcExecutionOptions中需要设置maxRetries为0,默认是3次,如果不设置成0的话,会导致数据重复
  • KafkaSink实现Exactly-once: 它通过在KafkaSinnk.builder中设置setDeliveryGuarantee为exactly-once就可以了
  • 自定义Sink: 同样的也分为,SinkFunction接口和RichSinkFunction类,区别参考上文的富函数类之间的区别

6. Flink异步IO机制

flink的异步IO主要用于跟外部的第三方组件进行交互的场景,传统的IO在链接第三方组件时发送一个请求是需要等待它回复才可以再次发送的,这样就大大的降低了Flink的吞吐。异步IO就是解决这个问题的,它允许Flink同时发送多个请求然后同时返回给你结果,不用等待一个一个请求的返回,如下图所示

在和第三方交互的时候,如果单从提高吞吐来说,是可以通过提高并行度来提高的,但是并行度的提高意味这需要更多的task,更多 内存缓存和更多的网络链接的开销,而异步IO只是在原来的task上反复利用同一个task的资源就可以达到效果。

下面介绍下用异步IO的方式链接MySQL,它的通过Java的VertX来实现的,核心代码是继承RichAsyncFunction类,并实现对应的open()和asyncInvoke()这两个方法,其中open方法用来链接MySQL资源,asyncInvoke方法是具体实现查询语句的方法

相关推荐
Elastic 中国社区官方博客5 小时前
通过自主 IT 平台和 Elastic 迈出可观测性的下一步
大数据·elasticsearch·搜索引擎·全文检索·可用性测试
成长之路5148 小时前
【数据集】A股上市公司深度合成算法业务数据(2001-2024)
大数据
GIS数据转换器10 小时前
延凡智慧水务系统:引领行业变革的智能引擎
大数据·人工智能·无人机·智慧城市
2601_9495394511 小时前
家用新能源 SUV 核心技术科普:后排娱乐、空间工程与混动可靠性解析
大数据·网络·人工智能·算法·机器学习
莫叫石榴姐11 小时前
字节广告数开一面 | 实习
大数据·数据仓库·面试
T062051412 小时前
【面板数据】地级市人力资本水平测算数据(1990-2024年)
大数据
TDengine (老段)12 小时前
TDengine IDMP 可视化 —— 饼图
大数据·数据库·人工智能·物联网·时序数据库·tdengine·涛思数据
Flying pigs~~12 小时前
从“踩坑”到“可控”:大模型 Prompt 工程实战总结与进阶方法论
大数据·人工智能·大模型·prompt·提示词工程
白眼黑刺猬13 小时前
实时库存预警: 如何实现秒级更新且保证在高并发下不出现“超卖”显示错误?
大数据·面试·职场和发展
云栖梦泽13 小时前
【AI】AI安全工具:常用AI安全检测工具的使用教程
大数据·人工智能·安全