Apache Flink:如何启用" upsert模式"对于动态表格?

时间:2018-02-01 03:43:10

标签: apache-flink flink-streaming flink-sql

我已经看到几个提及" upsert模式" 基于Flink文档和官方Flink博客中的唯一键的动态表。但是,我没有看到任何关于如何在动态表上启用此模式的示例/文档。

示例:

  • Blog post

      

    通过更新模式在流上定义动态表时,我们可以在表上指定唯一键属性。在这种情况下,关于键属性执行更新和删除操作。 更新模式在下图中可视化。

  • Documentation

      

    转换为 upsert流的动态表需要(可能是复合的)唯一键

所以我的问题是:

  • 如何在Flink中的动态表上指定唯一键属性?
  • 如何在update / upsert /&#34中放置动态表;替换"模式,而不是追加模式?

3 个答案:

答案 0 :(得分:3)

链接资源描述了两种不同的场景。

  • blog post讨论了upsert DataStream -> Table转换。
  • documentation描述了反向上传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_VALUEbuild-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)类似于:

  1. concat(ts,ip)asordered_ip
  2. MAX(ordered_ip)为ordered_ip
  3. 将(ordered_ip)提取为ip