赞
踩
Connector 的作用就相当于一个连接器,连接 Flink 计算引擎跟外界存储系统。
目前常用的 Connector 有以下几种:

// 从文本文件中读取数据
env.readTextFile(path);
// 以文本的形式读取该文件中的内容
env.readFile(fileInputFormat, path);
// 将结果已文本格式写出到文件中
DataStream.writeAsText(path)
// 将结果已 csv 格式写出到文件中
DataStream.writeAsCsv(path)
// 根据 Socket 的 host name 及 port,创建基于 Socket 的 source
env.socketTextStream(hostname, port);
// 将结果写入到一个socket中
DataStream.writeToSocket(hostname, port)
// 直接基于内存中的集合或者迭代器创建source
env.fromCollection(conllectionA or iteratorB);
// or
env.fromElements(arrayC);
// 将结果直接标准输出
DataStream.print();
// 将结果直接表春错误输出
DataStream.printToErr();
Flink 里已经提供了一些绑定的 Connector,例如 kafka source 和 sink,Es sink等。
该部分是 Flink 项目源代码里的一部分,但是真正意义上不算作 Flink 引擎相关逻辑,并且该部分没有打包在二进制的发布包里面。在提交 Job 时候需要注意, job 代码 jar 包中一定要将相应的 connetor 相关类打包进去,否则在提交作业时就会失败,提示找不到相应的类,或初始化某些类异常。
Apache Bahir 最初是从 Apache Spark 中独立出来的项目,提供不限于 Spark 相关的扩展/插件、连接器和其他可插入组件的实现。通过提供多样化的流连接器(streaming connectors)和 SQL 数据源扩展分析平台的覆盖面。如有需要写到 flume、redis 的需求的话,可以使用该项目提供的 connector。
流计算中经常需要与外部存储系统交互,比如需要关联 MySQL 中的某个表。
一般来说,如果用同步 I/O 的方式,会造成系统中出现大的等待时间,影响吞吐和延迟。为了解决这个问题,异步 I/O 可以并发处理多个请求,提高吞吐,减少延迟。

Async 的原理可参考官方文档:
https://ci.apache.org/projects/flink/flink-docs-release-1.3/dev/stream/asyncio.html
Kafka 是一个分布式的、分区的、多副本的、 支持高吞吐的、发布订阅消息系统。生产环境环境中 Flink 经常会跟 kafka 进行一些数据交换。
Flink 提供了现成的构造FlinkKafkaConsumer、Producer 的接口,可以直接使用。

Kafka 有多个版本,多个版本之间的接口协议会不同。Flink 针对不同版本的 kafka 有相应的版本的 Consumer 和 Producer。例如:针对 08、09、10、11 版本,Flink 对应的 consumer 分别是 FlinkKafkaConsumer 08、09、010、011,producer 也是。
kafka 中数据都是以二进制 byte 形式存储的。读到 Flink 系统中之后,需要将二进制数据转化为具体的 java、scala 对象。所以需要实现一个 schema 类,定义如何序列化和反序列数据。

反序列化
反序列化时需要实现 DeserializationSchema 接口,并重写 deserialize(byte[] message) 函数。
如果是反序列化 kafka 中 kv 的数据时,需要实现 KeyedDeserializationSchema 接口,并重写 deserialize(byte[] messageKey, byte[] message, String topic, int partition, long offset) 函数。
常用的序列化反序列化的 schema 类
SimpleStringSchema,按字符串方式进行序列化、反序列化。
TypeInformationSerializationSchema,它可根据 Flink 的 TypeInformation 信息来推断出需要选择的 schema。
JsonDeserializationSchema 使用 jackson 反序列化 json 格式消息,并返回 ObjectNode,可以使用 .get(“property”) 方法来访问相应字段。
Flink 提供非常好的封装来设置作业从 kafka 消费数据最开始的起始位置。在构造好的 FlinkKafkaConsumer 类后面调用如下相应函数,即可设置合适的起始位置。

因为业务的需要,Kafka 可能会有 topic 的增加或 partition 的扩容,Flink 可以动态的监测到 topic 和 partition 的变化。

Flink kafka consumer commit offset 方式需要区分是否开启了 checkpoint。

使用 EventTime 属性时,需要指定从消息中提取时戳和生成水位的函数。
FlinkKakfaConsumer 构造的 source 后直接调用 assignTimestampsAndWatermarks 函数设置水位生成器的好处是此时是每个 partition 一个 watermark assigner,如下图。source 生成的时戳为多个 partition 时戳对齐后的最小时戳。此时在一个 source 读取多个 partition,并且 partition 之间数据时戳有一定差距的情况下,因为在 source 端 watermark 在 partition 级别有对齐,不会导致数据读取较慢 partition 数据丢失。

所以对于 EventTime 的情况下,建议在 Source 后尽快设置 Timestamp 和 Watermark。
使用 FlinkKafkaProducer 往 kafka 中写数据时,如果不单独设置 partition 策略,会默认使用 FlinkFixedPartitioner。

Flink kafka 09、010 版本下,通过 setLogFailuresOnly 为 false,setFlushOnCheckpoint 为 true,能达到 at-least-once 语义。
setLogFailuresOnly,默认为 false,是控制写 kafka 失败时,是否只打印失败的 log 不抛异常让作业停止。
setFlushOnCheckpoint,默认为 true,是控制是否在 checkpoint 时 fluse 数据到 kafka,保证数据已经写到 kafka。否则数据有可能还缓存在 kafka 客户端的 buffer 中,并没有真正写出到 kafka,此时作业挂掉数据即丢失,不能做到至少一次的语义。
Flink kafka 011 版本下,通过两阶段提交的 sink 结合 kafka 事务的功能,可以保证端到端精准一次。
详情参考:https://www.ververica.com/blog/end-to-end-exactly-once-processing-apache-flink-apache-kafka
Q1: 在 Flink consumer 的并行度的设置:是对应 topic 的 partitions 个数吗?要是有多个主题数据源,并行度是设置成总体的 partitions 数吗?
A: 这个并不是绝对的,跟 topic 的数据量也有关,如果数据量不大,也可以设置小于 partitions 个数的并发数。但不要设置并发数大于 partitions 总数,因为这种情况下某些并发因为分配不到 partition 导致没有数据处理。
Q2: 如果 partitioner 传 null 的时候是 round-robin 发到每一个 partition?如果有 key 的时候行为是 kafka 那种按照 key 分布到具体分区的行为吗?
A: 如果在构造 FlinkKafkaProducer 时,如果没有设置单独的 partitioner,则默认使用 FlinkFixedPartitioner,此时无论是带 key 的数据,还是不带 key。如果主动设置 partitioner 为 null 时,不带 key 的数据会 round-robin 的方式写出,带 key 的数据会根据 key,相同 key 数据分区的相同的 partition,如果 key 为 null,再轮询写。不带 key 的数据会轮询写各 partition。
Q3: 如果 checkpoint 时间过长,offset 未提交到 kafka,此时节点宕机了,重启之后的重复消费如何保证呢?
A: 首先开启 checkpoint 时 offset 是 Flink 通过状态 state 管理和恢复的,并不是从 kafka 的 offset 位置恢复。在 checkpoint 机制下,作业从最近一次 checkpoint 恢复,本身是会回放部分历史数据,导致部分数据重复消费,Flink 引擎仅保证计算状态的精准一次,要想做到端到端精准一次需要依赖一些幂等的存储系统或者事务操作。
以上内容均来自对 https://www.bilibili.com/video/av56902622/ 的学习总结。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。