Apache Beam 管道中的连续状态

Posted

技术标签:

【中文标题】Apache Beam 管道中的连续状态【英文标题】:Continuous state in Apache Beam pipeline 【发布时间】:2017-11-09 15:57:05 【问题描述】:

我正在为数据流运行器开发光束管道。我的用例中需要以下功能。

    从 Kafka 主题读取输入事件。每个 Kafka 消息值派生 [userID, Event] 对。 对于每个userID,我需要维护一个profile,并且基于当前的Event,可能会更新profile。如果 profile 更新: 更新的profile 已写入输出流。 管道中userID 的下一个Event 应参考更新后的配置文件。

我正在考虑使用 Beam 中提供的状态功能,而不依赖于外部键值存储来维护用户配置文件。这对于当前版本的梁(2.1.0)和dataflow runner 是否可行?如果我理解正确,则状态的范围仅限于单个窗口触发中的元素(即即使对于GlobalWindow,状态也将范围限制为由触发器引起的窗口的单个触发中的元素)。我在这里遗漏了什么吗?

【问题讨论】:

【参考方案1】:

State 非常适合您的用例。

唯一的更正是状态被限定为单个窗口,但触发器触发不会影响它。因此,如果您的状态很小,您可以将其存储在全局窗口中。当有新元素到来时,可以使用状态,根据需要输出元素,对状态进行修改。

唯一需要考虑的是,如果您有无限数量的用户 ID,那么状态可能会变成多大。例如,您可能想要一个不活动计时器在一段时间后清除旧的用户状态。

如果您还没有阅读它们,博客文章 Stateful Processing with Apache Beam 和 Timely (and Stateful) Processing with Apache Beam 很好地介绍了这些概念和 API。

【讨论】:

感谢您的回答。由于状态是每个窗口,而不是窗口触发,因此它绝对有用。因此,带有触发器的全局窗口(或更长持续时间的固定时间窗口)后跟GroupByKey on userID 将保证 userID 的记录将被传递到保存用户状态的同一个工作人员。在有状态 DoFn 中使用的(setRelativeoffset)不活动计时器已经处理每个键和窗口的计时器。我的理解正确吗? 基本上——但它更容易。 Stateful DoFn 的使用已经是 per key,因此您不需要在 state 之前使用 GroupBykey,也不需要使用触发器。只需设置一个窗口来设置您希望状态保留多长时间,然后使用用户 ID 作为键执行 Stateful DoFn。 酷!这真的很有帮助,因为 GroupByKey 在数据流中非常昂贵。当我们需要在它过期之前将某些东西从窗口中取出时,触发器仍然有意义。在每次窗口触发中,都会更新状态,下一次触发将引用更新后的状态。 触发器不会影响有状态的 DoFn。您的有状态 DoFn 将在输入元素到达时输出(在 processElement 中)或在它设置的计时器触发时(在 processTimer 中)。仅当您 DoFn 之后有其他聚合时,才需要触发。

以上是关于Apache Beam 管道中的连续状态的主要内容,如果未能解决你的问题,请参考以下文章

Dataflow GCP(Apache Beam)-连续读取大量文件(OutOfMemory)

使用 Python 处理 Apache Beam 管道中的异常

防止 Apache Beam / Dataflow 流 (python) 管道中的融合以消除管道瓶颈

使用 Java 写入数据库时​​ Apache Beam 管道中的异常处理

如何组合两个结果并将其传递到 apache-beam 管道中的下一步

Apache Beam实战指南 | 大数据管道(pipeline)设计及实践