
回复
作者 | antigeneral了呀
来源 | 大数据羊说(ID:young_say)
转载请联系授权(微信ID:___antigeneral)
大家好,我是老羊,今天我们来学习 Flink SQL 中的 Deduplication 去重以及如何通过 Deduplication 操作获取最新的状态。
其中:
ROW_NUMBER()
:标识当前数据的排序值PARTITION BY col1[, col2...]
:标识分区字段,代表按照这个 col 字段作为分区粒度对数据进行排序ORDER BY time_attr [asc|desc]
:标识排序规则,必须为时间戳列,当前 Flink SQL 支持处理时间、事件时间,ASC 代表保留第一行,DESC 代表保留最后一行WHERE rownum = 1
:这个子句是一定需要的,而且必须为 rownum = 1博主这里举两个案例:
星星
,月亮
,太阳
的用户数分别有多少。
输出结果:
可以看到其有回撤数据。
其对应的 SQL 语义如下:
数据源
:消费到 Kafka 中数据后,将数据按照 partition by 的 key 通过 hash 分发策略发送到下游去重算子Deduplication 去重算子
:接受到上游数据之后,根据 order by 中的条件判断当前的这条数据和之前数据时间戳大小,以上面案例来说,如果当前数据时间戳大于之前数据时间戳,则撤回之前向下游发的中间结果,然后将最新的结果发向下游(发送策略也为 hash,具体的 hash 策略为按照 group by 中 key 进行发送),如果当前数据时间戳小于之前数据时间戳,则不做操作。次算子产出的结果就是每一个用户的对应的最新等级信息。Group by 聚合算子
:接受到上游数据之后,根据 Group by 聚合粒度对数据进行聚合计算结果(每一个等级的用户数),发往下游数据汇算子数据汇
:接收到上游的数据之后,然后输出到外部存储引擎中
输出结果:
可以看到这个处理逻辑是没有回撤数据的。其对应的 SQL 语义如下:
数据源
:消费到 Kafka 中数据后,将数据按照 partition by 的 key 通过 hash 分发策略发送到下游去重算子Deduplication 去重算子
:处理时间语义下,如果是当前 key 的第一条数据,则直接发往下游,如果判断(根据 state 中是否存储过改 key)不是第一条,则直接丢弃数据汇
:接收到上游的数据之后,然后输出到外部存储引擎中注意:
在 Deduplication 关于是否会出现回撤流,博主总结如下:
- ⭐ Order by 事件时间 DESC:会出现回撤流,因为当前 key 下
可能会有
比当前事件时间还大的数据- ⭐ Order by 事件时间 ASC:会出现回撤流,因为当前 key 下
可能会有
比当前事件时间还小的数据- ⭐ Order by 处理时间 DESC:会出现回撤流,因为当前 key 下
可能会有
比当前处理时间还大的数据- ⭐ Order by 处理时间 ASC:不会出现回撤流,因为当前 key 下
不可能会有
比当前处理时间还小的数据