流处理体系结构:未来事件会影响过去的结果



我是流处理(kafka streams/flink/storm/spark/etc(的新手,并试图找出处理现实世界问题的最佳方法,这里用一个玩具示例表示。 我们的发布/数据摄取与 Kafka 绑定,但在流处理器框架/方法方面没有特别的依恋。

从理论上讲,假设我有一个零星发出浮点值的源。 此外,在任何给定点上,都有一个乘数 M 应用于此源的值;但 M 可以改变,而且至关重要的是,我可能要晚得多才发现变化——甚至可能不是"按变化顺序"。

我正在考虑在卡夫卡中将其表示为

"Values": (timestamp, floating point value) - the values from the source, tagged with their emission time.
"Multipliers": (timestamp, floating point multiplier) - indicates M changed to this floating point multiplier at this timestamp.

然后,我会想创建一个输出主题,比如"结果",使用标准流处理框架,连接两个流,并且只是将值中的每个值乘以乘数确定的当前乘数。

但是,根据我的理解,这是行不通的,因为发布到乘数的新事件可能会对已写入结果流的结果产生任意大的影响。 从概念上讲,我希望有一个类似结果流的东西,该流在上次发布到乘数的事件时针对值中的所有值是最新的,但可以在进一步的值或乘数事件进入时"重新计算"。

使用 kafka 和主要流处理器实现/构建这一点有哪些技术?

例:

最初

Values = [(1, 2.4), (2, 3.6), (3, 1.0), (5, 2.2)]
Multipliers = [(1, 1.0)]
Results = [(1, 2.4), (2, 3.6), (3, 1.0), (5, 2.2)]

Values = [(1, 2.4), (2, 3.6), (3, 1.0), (5, 2.2)]
Multipliers = [(1, 1.0), (4, 2.0)]
Results = [(1, 2.4), (2, 3.6), (3, 1.0), (5, 4.4)]

最后,在发布到乘数的另一个事件之后(也发出了一个新值(:

Values = [(1, 2.4), (2, 3.6), (3, 1.0), (5, 2.2), (7, 5.0)]
Multipliers = [(1, 1.0), (4, 2.0), (2, 3.0)]
Results = [(1, 2.4), (2, 10.8), (3, 3.0), (5, 4.4), (7, 10.0)]

我只熟悉 Spark,为了使它像您描述的那样工作,您希望在收到新的乘数值时有选择地"更新"以前的结果,同时将最高索引乘数应用于尚未应用乘数的新值。AFAIK,Spark 本身不会让你使用流来做到这一点(你需要缓存和更新旧结果,你还需要知道哪个是用于新值的乘数(,但你可以对逻辑进行编码,以便将你的"结果"主题写入常规数据库表,当你收到一个新的乘数时, "值"数据帧中的所有后续事件将仅使用该值,但您将执行一次性检查,以查找结果表中是否有值现在需要更新以使用新的乘数,并仅更新数据库表中的这些值。

您的结果使用者必须能够处理插入和更新。您可以将 Spark 与任何具有连接器的数据库一起使用来实现此目的。

或者,您可以使用SnappyData,它将Apache Spark变成一个可变的计算+数据平台。使用 Snappy,您可以将值和乘数作为常规流式处理数据帧,并将结果作为数据帧设置作为 SnappyData 中的复制表。当您处理乘数流中的新条目时,您将更新结果表中存储的所有结果。这也许是完成您正在尝试做的事情的最简单方法

最新更新