我们都知道Flink在流式处理上性能强大,且很好地支持ExactlyOnce语义;且这也是Flink核心的技术点,所以成为面试官喜欢追问的一个话题:Flink恰巧语义一次消费,怎么保证?
上述思维导图中也进行了详细地描述:Flink_思维导图(干货).xmind.zip截图如下:
如果面试官问到,可以大致从这些方面进行分析:
Flink是由source --> transformation --> sink三部分组成;也就是说Flink要实现ExactlyOnce语义与这三者脱不了干系;
- 数据源Source,首先要支持ExactlyOnce,比如Kafka;
- 接着需要对Flink开启checkpoint机制;即开启状态后端,保存其偏移量及中间状态数据;
- Sink端需要支持写覆盖也就是我们经常说的幂等性或者支持事务(两阶段提升)
Flink中的checkpoint具体操作如下:
使用FlinkKafkaConsumer,开启CheckPointing,偏移量会保存通过CheckPoint保存到StateBackend中,并且默认会将偏 移量写入Kafka的特殊topic中,即:__consumer_offsets
FlinkKafkaConsumr的setCommitOffsetsOnCheckpoints参数默认true,即将偏移量写入到Kafka特殊的Topic中,目的是为了监控或重启任务没有指定savePoint时可以接着一起的偏移量继续消费并且设置CheckpointingMode.EXACTLY_ONCE
Barrier【隔离带】可以保证一个流水线中的所有算子都处理成功了,才会对该条数据做CheckPoint
存储系统不支持覆盖的话,就得要支持事务,成功了提交事务和更新偏移量,如果失败可以回滚且不更新偏移量