数据连接与集成构建管道Incremental pipelines保持高性能

注意:以下翻译的准确性尚未经过验证。这是使用 AIP ↗ 从原始英文文本进行的机器翻译。

保持高性能

增量变换可以通过确保在管道更新时仅处理新行来帮助最小化资源使用。在Foundry中,增量变换只能向数据集添加新行,不能替换或删除行。这可能同样适用于数据摄取。由于每次运行通常只处理少量数据,这些添加通常很小,但在呈现活动视图时必须一起考虑。

通常这没问题,但当成千上万的小更新累积时(这可能在数周或数月不间断搭建后发生,取决于频率),读取性能可能开始下降。这可能由几个相关因素引起,如下所述。

可能的原因

大量文件

数据集中有太多文件会导致访问当前视图数据的后端请求变慢。这可能导致预览不可用问题,Contour中的故障,以及在变换中尤其是Python变换中出现严重的缓慢,因为在该语言环境中加载文件有特殊的开销。

随着时间的推移,涉及活动数据集视图的任何操作都将被低效的数据读取所主导,以至于最初在几分钟内运行的变换最终需要数小时或数天。在极端情况下,后端请求可能会超时,导致搭建失败。

大量事务

与拥有太多文件类似,视图中的太多事务也会导致缓慢。然而,这种缓慢不仅在请求文件时发生,还在解析视图范围时发生,这会影响数据集功能,例如计算统计数据、加载历史记录等。在变换中,这种缓慢将在预计算阶段表现出来,即在设置环境且没有Spark细节可用之前,使得问题难以调试。

通常事务与文件一起累积,但在某些情况下,即使文件数量相对较少,空事务也会导致问题。反之,即使事务数量相对较少,如果每个事务包含很多文件,也可能导致大量文件。

可能的解决方案

定期快照

保持增量管道高效的最简单且在某些情况下最有效的解决方案是运行定期快照。快照将重新处理完整数据并用新的视图替换输出,可以高效地进行分区。快照是一种计算密集型操作,这就是为什么增量处理通常优于常规处理,但偶尔的快照可以帮助防止在同一视图中积累过多的文件或事务。为了确定快照频率,管理员应在读取和写入数据的性能之间取得平衡。

快照事务具有级联效应,其中每个使用已快照输入的增量变换都会自行快照。我们只需对变换的一个输入进行快照,而不是直接强制增量变换运行快照,并让变换应用程序确定增量变换也需要快照。因此,设置增量管道以定期快照的一个有用方法是设置一个伪输入,该输入将在预定快照计划上进行搭建,并使伪输入始终以快照模式运行。

定期快照有几个缺点,如下所述:

  • 快照可能会使血缘关系复杂化,因为伪输入会出现在搜索和文件夹结构中,这可能会造成混淆。
  • 即使不常进行,快照也可能非常昂贵。
  • 在快照运行时,无法通过管道传播更新,这可能会干扰服务级协议(SLA)。
  • 快照不适用于原始数据集,例如由数据连接同步支持的数据集。
  • 并非每个变换都以支持快照的方式编写(尽管我们建议它们始终如此)。

数据集投影

处理增量积累的最推荐方法是为相关数据集添加一个数据集投影。数据集投影为在数据集中查询数据提供了一种替代机制,并独立于规范数据集存储和更新。由于这些特性,数据集投影可以突破增量计算的仅追加模型,并在数据量增长时自动重组其内部数据表示。这称为压缩——压缩确保从投影读取始终高效,无论规范数据集中有多少文件或事务。

这对增量管道特别有用,因为数据集投影不需要与规范数据集完全同步,读者就能从提高的性能中受益。所有Foundry产品都知道如何结合来自投影和规范数据集的数据来重建视图,就像投影不存在一样。例如,如果数据集有100个增量事务,并且有一个用前99个事务构建的投影,那么99个将从投影中读取,只有一个从数据集中读取。因此,通常每天或每周更新数据集投影就足够了,使其在维护上非常便宜。

请注意,由于数据集投影是与规范数据集分开的资源,它可以随时构建,即使规范数据集本身正在搭建(反之亦然)。读者将使用根据有效事务当前状态的任何状态。例如,如果数据集正在搭建事务10,并且投影同时开始构建,它将从事务9读取。在这种情况下查询数据的读者将从投影中读取事务1-8,并从数据集中读取事务9,有效地看到与直接从数据集中读取相同的数据。

数据集投影的缺点包括:

  • 数据集投影使用的存储空间比单独的数据集更多。
  • 数据集投影不能与Foundry保留开箱即用。
  • 数据集投影不会以任何方式修改规范数据集(因此如果删除投影,读取将再次变得低效)。

保留策略

有时,管道的应用案例不需要在平台上永久保留历史数据,只需保留最近的事务即可,这可以使用Foundry保留自动完成。在这种情况下,增量管道可以在不进行特殊考虑的情况下构建,只要变换逻辑不包括任何跨事务依赖(如聚合或差分计算)。必须在Python变换的增量装饰器中设置一个特殊的allow_retention标志(否则DELETE事务将触发快照运行)。

保留策略更改的缺点包括:

  • 历史数据的丢失。
  • 如果事务在数据方面不是自包含的单元,保留策略可能导致不一致的状态(例如,结束事件没有匹配的开始事件)。

其他可考虑的选项

中止事务

在某些情况下,事务会提交零文件或仅包含空文件。这些事务对视图没有影响,但它们被视为有效更新,并将触发计划和所有相关的副作用,可能导致计算浪费。空事务还可能大大增加文件和事务的数量。

最好在源头避免空事务,这通常是数据连接同步。数据连接将始终中止没有文件的事务,但仍可能生成空文件。空事务可能是自定义插件的一个特殊问题;有时可能无法修改插件以避免空事务(例如,如果需要非空事务来更新数据连接增量元数据)。在其他情况下,变换或其他方式可能提交无文件事务。

为了最大限度地减少这些空或无文件事务的影响,我们可以在管道中最上游的变换明确中止事务。当我们检测到收到空输入或以空输出结束时,可以调用.abort()在输出对象上;这将导致任务被中止,连同其事务一起。中止的事务实际上被取消,不会触发计划或引起任何副作用。中止事务将打破链条并停止空事务沿着管道传播。中止事务也不会贡献失败统计数据(而故意使搭建失败会贡献失败统计数据)。

请注意,中止的搭建被视为成功,并将推进输入事务指针。因此,使用非空输入中止将丢弃数据,如果您希望因其他原因(如失败的前置条件)停止搭建,这可能不是所需的。

变更日志数据集

变更日志逻辑使您能够在仅追加事务上实现编辑语义,从而可以在增量管道中可靠地进行合并和聚合。然而,除了前面提到的文件和事务计数问题之外,在仅追加事务上实现编辑语义可能会使行计数无限增长,使得变换性能在达到状态解析阶段时越来越差(或需要单独的快照)。

对于此类管道,控制行计数有些棘手。快照是可行的,并且在存在部分状态的中间变换中可能有很大帮助(因为这些状态在完全重建中大多消失)。但要充分受益于快照,逻辑必须将行折叠到其最新状态,这并不总是理想的(在某些情况下,我们可能希望了解行在任何给定时间点的状态,而不仅仅是最新状态)。数据集投影只能提供有限的帮助。如果行不是原子单元,保留策略可能没有预期效果(例如,我们可能会遇到没有匹配开始事件的结束事件)。因此,在设计此类管道时必须特别小心。