- Append-only 流 和 Retract 流
在将动态表写入外部系统时,有三种流的类型:Append-only 流,Retract 流,Upsert 流。目前工作中用到的应该是前两类流比较多。
Append-only 流:Append-only 流是指只追加数据的流,不记录数据的变化。它只记录新增的数据,不对已有数据进行更新或删除操作。
Retract 流:Retract 流用于记录增量计算的结果,它会对每条记录进行标记,标识该记录是新增、更新还是删除。当某条记录发生变化时,Kafka 消息记录的 key 当成主键处理,旧的记录会被标记为删除,新的记录会被标记为新增,这样可以保留历史数据的变化信息。
Flink sql 作业中使用group_by, row_number 等操作,可能要去更新之前的结果值,会产生Retract流。
(动态表类型
Apache Flink 1.12 Documentation: 动态表 (Dynamic Table) )
2. upsert-kafka
在Flink1.12版本中, 新增了一个 upsert connector(upsert-kafka),该 connector 扩展自现有的 Kafka connector,工作在 upsert 模式(FLIP-149)下。新的 upsert-kafka connector 既可以作为 source 使用,也可以作为 sink 使用,并且提供了与现有的 kafka connector 相同的基本功能和持久性保证,因为两者之间复用了大部分代码。
(UpsertKafka类型
Apache Flink 1.12 Documentation: Upsert Kafka SQL 连接器 )
作为 sink 端使用时,upsert-kafka 连接器可以消费 retract流。它会将 INSERT/UPDATE_AFTER 数据作为正常的 Kafka 消息写入,并将 DELETE 数据以 value 为空的 Kafka 消息写入(表示对应 key 的消息被删除)。
测试案例:
sql
--计算统计level下的数量
--定义源表
CREATE TABLE kafkasource_table(
userId varchar, --用户id
level varchar, --级别
amount varchar, --金额
proc time ASPROCTIME())
WITH(
'topic'='xx',
...
)
--定义结果表
CREATE TABLE kafka_sink(
level VARCHAR, --级别
uv VARCHAR, --此级别的用户数量
PRIMARY KEY(level) NOT ENFORCED
)WITH(
'connector'='upsert-kafka-x',
'value.format'='json',
'value.fields-include'='ALL',
'key.format'='json',
'topic'='xx',
'sink.parallelism'='1'
...
)
--处理逻辑
create view view AS
select
level,
count(l) as uv
from
( select userId, level,
ROW NUMBER()OVER ( PARTITION BY userId ORDER BY cast (amount asint) desc) as rn
from kafka_source_table )
where rn = 1
group by level
;
into kafka sink
select
level,
cast(uv as string) as uv
from view
;
Kakfa输入:
inputl: {"userId":"01","level":"A","amount":"30"}
input2: {"userId":"02","level":"B","amount":"30"}
input3: {"userId":"01","level":"B","amount":"40"}
Kakfa输出:
outputl: {"level":"A","uv":"1"}
output2: {"level":"B","uv":"1"}
output3:
null
{"level":"B","uv":"2"}
回撤流:
outputl:
+-------+----+----------+
| level | uv | RowKind |
+-------+----+--------+
| A | 1 | INSERT |
+-------+----+----------+
output2:
+-------+----+----------+
| level | uv | RowKind |
+-------+----+--------+
| B | 1 | INSERT |
+-------+----+----------+
output3:
+-------+----+----------+
| level | uv | RowKind |
+-------+----+--------+
| A | 1 | DELETE |
+-------+----+----------+
+-------+----+----------+
| level | uv | RowKind |
+-------+----+-------+
| B | 1 | UPDATE_BEFORE|
+-------+----+----------+
+-------+----+----------+
| level | uv | RowKind |
+-------+----+--------+
| B | 2 | UPDATE_AFTER|
+-------+----+----------+