8

Flink整合面向用户的数据流SDKs/API(Flink关于弃用Dataset API的论述) - dhf123

 1 year ago
source link: https://www.cnblogs.com/dhavin/p/16338344.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Flink整合面向用户的数据流SDKs/API(Flink关于弃用Dataset API的论述)

Flink提供了三种主要的sdk/API来编写程序:Table API/SQL、DataStream API和DataSet API。我们认为这个API太多了,建议弃用DataSet API,而使用Table API/SQL和DataStream API。当然,这说起来容易做起来难,所以在下面,我们将概述为什么我们认为太多的api对项目和社区有害。然后,我们将描述如何增强Table API/SQL和DataStream API以包含DataSet API的功能。
在本FLIP中,我们将不描述如何增强Table API/SQL和DataStream的所有技术细节。目标是在弃用DataSet API的想法上达成共识。必须有后续的flip来描述我们所维护的api的必要更改。

为什么Flink有三个api?

这三种api在项目的生命周期中被有机地开发出来,最初是为特定的用例设计的。DataSet API是Flink最古老的API,支持有界数据的批处理执行。有些人可能不记得了,但Flink最初是一个批处理程序。在早期,社区意识到其基于管道的体系结构非常适合流处理,这就产生了DataStream API。后者是为无界的流用例开发的,具有处理状态、事件时间和窗口的特殊设施。随着Flink在分析领域的流行,Table API/SQL被引入,以提供支持批处理和流处理的高级关系API。
对于下面的讨论,理解每个API的区别特性将会很有帮助。

DataSet API:

  • 只支持有界源
  • 没有为事件时间/窗口提供特殊支持
  • 全有或全无输出:作业要么产生数据,要么不产生数据
  • 用于大规模批处理作业的细粒度的、基于区域的故障转移。执行中某一部分的失败并不一定需要重新启动整个拓扑
  • 高效的数据库式操作符:散列连接、合并连接、对使用输入数据有界知识的聚合进行排序/分组

DataStream数据API:

  • 源可以是有界的,也可以是无界的
  • 对事件时间和窗口的特殊支持
  • 基于水印或检查点的“增量”输出
  • 故障恢复检查点,这意味着在一个算子失败的情况下重新启动整个拓扑
  • 你可以执行有界程序,但效率不高:
    • 悲观的假设,没有结束标识,“你不知道接下来会发生什么”
    • 对于聚合,需要将所有键保存在一个“哈希映射”中
    • 对于事件时间处理,我们需要保持多个“窗口”打开
    • 没有基于阻塞、持久洗牌的细粒度恢复

Table/SQL API:

  • 有界和无界源
  • 一个声明性API,以及SQL
  • 数据有一个预先知道的结构,因此允许额外的优化,例如,分组时只反序列化记录中需要的部分,完全处理二进制数据,以及整个查询优化
  • 同样的查询/程序可用于有界和无界源
  • 流和批处理的高效执行,这意味着对于有界执行,我们可以使用DataSet API使用的执行模型,对于流用例,使用DataStrem API的执行模型。这对用户来说是透明的。
  • 没有低级算子API,即没有计时器、状态
  • 不控制生成的执行DAG→查询优化器会阻止保存点兼容性

自然会出现这样的问题:“为什么社区最初不扩展DataSet API来处理无界/流式的工作负载,而是添加DataStream API ?”简单的回答是,我们当时没有花时间去思考一个API如何同时服务于两个用例。

为什么有太多的api不好呢?

我们看到当前局势存在两个主要问题:

当需要物理API时,重用Flink应用程序的无界处理和有界处理是不现实的:

我们认为,对于用户来说,编写一个管道来分析流数据/无界数据,然后希望重用相同的代码来处理有界数据/批处理数据是很常见的。例如,当你想处理S3的历史数据时,实时管道会从Kafka读取数据。理论上,可以对有界源使用DataStream API,但无法获得有效的执行或容错行为。如果出现故障,整个管道必须重新启动。这与DataSet API的执行模型不同,在该模型中,只需要重启单个操作或连接的子图,因为我们可以保留操作的中间结果。

如果您事先知道所有的输入,那么使用事件时间语义就会容易得多。水印可以总是“完美”的,因为没有早期或晚期数据,我们用于批处理式执行的算法和数据结构可以考虑到这一点。

DataSet和DataStream API有不同的可用连接器集,因为它们使用不同的API来定义源和接收。例如,你不能用批处理类型的作业从Kafka读取一个有界的区间。

最后,我们认为DataStream API的事件时间/窗口特性对于批处理也很有用。例如,当您想要处理时间序列数据时。目前,您可以使用DataStream API并处理低于标准的执行行为,或者使用DataSet API并使用排序/分组手动实现窗口。

用户必须提前在api之间做出选择:

这增加了认知负荷,使Flink对新用户来说更不容易接近。如果他们一开始就做出了错误的选择,那么如果没有大量的时间投资,他们将无法在以后转换。

另一个方面是,想要采用Flink的大型组织可能会因为不得不对工程师进行两种不同api及其潜在语义差异的培训而受挫,例如什么是延迟,什么是事件时间,以及它是否与批处理相关等。

我们建议弃用DataSet API,而使用Table API/SQL和DataStream API。为了实现这一点,我们需要增强Table API/SQL和DataStream API,使其成为以前使用DataSet API的情况下可用的替代品。我们将在这里概述所需的更改,但将更具体的计划推迟到后续的FLIPs。对于这个提议,我们只是想让社区就弃用DataSet API的总体想法达成共识,并概述其他API所需的变化。

对“幸存者”api的更改

Table/SQL API:

  • 必须容易在代码中内联定义源/接收器。这在FLIP-129:重构描述符API中进行了介绍,以在表API中注册连接器。
  • 我们应该在Table上有易于使用的“命令式”操作,也就是应该有“人体工程学”map/filter/flatMap。这些操作应该是面向行/记录的,而不是常规Table API操作的面向列的性质。这样用户就不必学习表达式DSL语法来编写操作。
  • 此外,我们还希望弃用/删除遗留表API批处理计划器以及批执行环境,因为它们与DataSet API互操作

DataStream数据API:

  • 我们需要一个适用于有界和无界源的源API。这在FLIP-27:重构源接口中有涉及。
  • 我们需要一个适用于无界和有界源的接收器API。这是由FLIP-143:统一汇聚API覆盖的
  • 我们需要定义一组通用的执行语义,用于批处理和流执行,这包括重新考虑DataStream API中的一些决策,使它们在一个统一的世界中工作。这在FLIP-134: DataStream API的批处理执行中得到了介绍
  • 当拓扑有界时,我们需要为DataStream程序使用高效的批处理式执行。这在FLIP-140中有涉及:为有界键控流引入批处理样式的执行
  • 特别是对于机器学习用例,我们需要对迭代计算的健壮支持。目前DataStream API中对迭代的支持应该被认为是实验性的,它不像DataSet API那样支持动态终止标准。然而,我认为我们需要在后续FLIP中解决这个问题。

哪些用例应该使用什么API/SDK

我们目前还没有明确的指南来指导用户应该使用哪种API。我们需要就建议达成一致,然后在文件和一般营销中积极推广它们。这可能会以决策树或其他图形化决策工具/应用的形式出现。

我们目前的想法总结如下:

  • 如果你有一个模式,没有“低级”操作→SQL/Table
  • 如果你需要显式控制执行图、操作、操作中的状态→使用DataStream API

也就是说,应该可以在Table API和DataStream API之间自由转换。FLIP-136:改善DataStream和Table API之间的互操作性使这些工作更加具体。

兼容性、弃用和迁移计划

DataSet API应该在文档和代码中标记为已弃用,并描述项目的未来方向。在即将到来的版本中。

  • 用户有足够的时间将现有的用例迁移到其他API,
  • 我们确信剩余的API足以覆盖DataSet API的用例,我们就应该删除DataSet API。

这取决于上面提到的后续FLIPs,所以当满足上面概述的条件时,这个FLIPs可以被认为是完整的。

重要的是要记住,我们不能简单地将DataSet API从一个版本移到下一个版本。这将是一个较长的过程,我们需要确保DataSet API的现有用户能够迁移并进行迁移。有些公司在DataSet API上投入了大量资金,但他们不能把它们抛在后面。

我们认为,如果可用api的重叠像DataStream和DataSet api那样明显,那么除了减少可用api的数量别无选择。理论上我们可以弃用DataStream API,支持DataSet API,但我们认为DataStream API是更广泛使用的API,而且目前它的功能也更齐全(请参阅事件时间处理和窗口)。这也与“批处理是流的一部分,批处理是流处理的严格子集”的思想产生了很好的共鸣。

关注gzh HEY DATA 一起交流更多。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK