我已经看到几个提及" upsert模式" 基于Flink文档和官方Flink博客中的唯一键的动态表。但是,我没有看到任何关于如何在动态表上启用此模式的示例/文档。
示例:
通过更新模式在流上定义动态表时,我们可以在表上指定唯一键属性。在这种情况下,关于键属性执行更新和删除操作。 更新模式在下图中可视化。
转换为 upsert流的动态表需要(可能是复合的)唯一键。
所以我的问题是:
答案 0 :(得分:3)
链接资源描述了两种不同的场景。
DataStream -> Table
转换。 Table -> DataStream
转换。以下讨论基于Flink 1。4。0(2018年1月)。
Upsert DataStream -> Table
转化
通过插入密钥将DataStream
转换为Table
本机不受支持,但在路线图上。同时,您可以使用追加Table
和带有用户定义聚合函数的查询来模拟此行为。
如果您的跟踪Table
Logins
附加了跟踪用户登录的架构(user, loginTime, ip)
,则可以将其转换为Table
上的关键字user
使用以下查询:
SELECT user, LAST_VAL(loginTime), LAST_VAL(ip) FROM Logins GROUP BY user
LAST_VAL
聚合函数是user-defined aggregation function,它始终返回最新的附加值。
对upsert DataStream -> Table
转换的原生支持基本上会以相同的方式工作,尽管提供了更简洁的API。
Upsert Table -> DataStream
转化
不支持将Table
转换为upsert DataStream
。这也在文档中正确反映出来:
请注意,将动态表格转换为DataStream时,仅支持附加和撤消流。
我们故意选择不支持up Table -> DataStream
转换,因为只有知道了关键属性才能处理upsert DataStream
。这些取决于查询,并不总是直接识别。开发人员有责任确保正确解释关键属性。如果不这样做会导致程序错误。为避免出现问题,我们决定不提供upsert Table -> DataStream
转换。
相反,用户可以将Table
转换为撤消DataStream
。此外,我们支持将UpsertTableSink
写入外部系统(例如数据库或键值存储区)的DataStream
。
答案 1 :(得分:2)
更新:从 Flink 1.9 开始,LAST_VALUE
是 build-in aggregate functions 的一部分,如果我们使用 Blink planner(这是自 Flink 1.11 以来的默认设置)。
假设上面 Fabian Hueske 的回复中提到的 Logins
表存在,我们现在可以简单地将其转换为 upsert 表:
SELECT
user,
LAST_VALUE(loginTime),
LAST_VALUE(ip)
FROM Logins
GROUP BY user
答案 2 :(得分:0)
Flink 1.8仍然缺乏这种支持。预计将来会增加这些功能:1)LAST_VAL 2)Upsert Stream <->动态表。
ps。 LAST_VAL()似乎不可能在UDTF中实现。聚合函数不提供附加的事件/过程时间上下文。阿里巴巴的Blink提供了LAST_VAL的替代实现,但是它需要另一个字段来提供订单信息,而不是直接提供事件/过程时间。这使得SQL代码很难看。 (https://help.aliyun.com/knowledge_detail/62791.html)
我的LAST_VAL解决方案(例如获取最新IP)类似于: