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 中使用的(setRelative
和 offset
)不活动计时器已经处理每个键和窗口的计时器。我的理解正确吗?
基本上——但它更容易。 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 管道中的异常处理