Flink DataStream API 消费binlog kafka实践

Flink提供了方便快捷的source类来消费kafka消息,因此只需要定义对应

复制代码
kafka source,配置kafka地址便可以消费kafka消息
KafkaSource<String> kafkaSource = KafkaSourceFactory.createDefaultSource(parameterTool, topic, groupId);
DataStreamSource<String> kafkaStream = env.fromSource(kafkaSource, WatermarkStrategy.noWatermarks(), "Kafka Source"); 

这里有几个问题

如何保证消息的顺序性

首先明白一点kafka能保证分区内有序,所以首先生产端需要保证有序,另外如果kafka是多个分区的,建议按照业务键路由到对应的分区,这样同一条业务数据产生的binlog kafka消息在被消费前是有序的。

如何保证flink消费的有序性呢?一种方式是flink的并行度和kafka分区保持一致或者少于kafka分区数;另外一种方式是使用flink的watermark机制生成 Watermark。而笔者的场景kafka分区只有一个,flink并行度有4个。因此对于笔者而言实际上只有一个flink节点消费kafka。

但是为了提高性能(见下),对数据流进行了keyBy,所以这里的关键是keyBy得是你的业务键

复制代码
// 再按 uuid keyBy,做过滤、MySQL 关联,通过侧输出分流
        SingleOutputStreamOperator<Void> keyedStream = afterMaxUmsId
                .keyBy(YourObject::getUuid)
                .process(new FieldDataEnrichAndRouteKeyedProcessFunction(parameterTool))
                .name("enrich and route");

这里需要注意,只有process里的处理逻辑才会保证数据流是按照你的keyBy进行了分组,如果你再对处理后的流,比如这里的keyedStream再次加工而不进行keyBy,是不会保证按照业务键分组的

如何优化性能,提高消费速度

前文提到,kafka分区只有一个,也就是只有一个实例消费kafka消息,这样消费端很慢,实际上也浪费了flink算子的并行度,因此第一步根据业务键进行了keyBy,分组后便能利用到并行的能力了。

如何避免重复消费

通常业务中会短时间内对同一条数据做多次变更,这样会导致多条binlog消息,如果每条都去处理的话,会造成资源消耗,拖慢整体性能。可以采用flink现成的"时间窗口+聚合函数"方案优化,在一个时间窗口内,仅保留binlog唯一id(ums_id_)最大的一条数据,过滤重复无效更新,降低资源消耗

复制代码
// 按 uuid 分组,5s 滚动窗口内用 aggregate 只保留 umsId 最大的那条
        long windowSec = parameterTool.getLong("window.max.umsId.seconds", 5L);
        DataStream<YourObject> afterMaxUmsId = parsedStream
                .keyBy(WorkRecordBasic::getUuid)
                .window(TumblingProcessingTimeWindows.of(Time.seconds(windowSec)))
                .aggregate(new MaxUmsIdAggregateFunction())
                .name("max umsId in window");
相关推荐
code2cat11 分钟前
【随笔】MCP工具重试:任务已经创建,响应丢了怎么办
数据库·mcp
wuyk5552 小时前
Spider-第10讲-SQLite持久化与去重
数据库·爬虫·sqlite
乌暮3 小时前
Spring AOP 与 Spring 事务:用大白话彻底理解原理与实践
java·数据库·spring boot·后端·sql·学习·spring
小此方4 小时前
Re:Mysql数据库基础篇(十二):什么是事务、事务解决了什么问题、事务的四大属性、事务的操作方式
数据库·mysql
flash俊杰5 小时前
v0.5-01 让桌面 AI 助手记得住:预算组装、递归摘要、长期记忆与评估基线
数据库·安全·架构
2501_933923256 小时前
redis:string类型常见命令
数据库·redis·缓存
byte轻骑兵7 小时前
时序数据库选型指南:Apache IoTDB 社区版实践与踩坑
数据库·人工智能·apache·时序数据库·iotdb
黄连木笛8 小时前
Redis Insight 汉化教程:Windows / macOS / Linux 设置中文界面(附繁體、教程汉化、关闭自动更新)
数据库·redis·缓存
nice_lcj5208 小时前
MySQL 存储引擎入门:InnoDB 和 MyISAM 到底怎么选
java·数据库·mysql·面试·innodb·存储引擎·myisam
古典和浪漫9 小时前
MVCC机制
数据库