0

DynamoDB 中的事务表

Transactions {transaction_id, customer_id, statment_id, transaction_date, transaction_amount}

DynamoDB 中的语句表

Statements {statement_id, customer_id, start_time, end_time, statement_amount}

任何一天都有数百万笔交易发生。我正在考虑使用 Flink 将交易金额聚合到使用 DynamoDB 流的语句金额中。

在任何给定的点上,我都需要知道属于一个语句的所有交易金额是否被汇总。即显示报表金额是否过期。本质上,我在谈论和解。我如何在 Flink 中实现这一点?

4

1 回答 1

1

KeyedProcessFunction使用类似 a 的东西来持续更新一些 Flink 状态是很容易的,这些状态在新事务被摄取时聚合statement_amount每个状态。statement_id但是,据我了解,问题是如何知道聚合何时完成,或者换句话说,Flink 何时处理了给定的所有事务statement_id

流处理应用程序总是面临这个问题。与批处理不同,批处理可以简单地处理所有数据然后产生结果,而使用流处理,我们一次处理一条记录,不知道将来会发生什么,也不知道有多少延迟。

这导致我们在延迟完整性之间进行权衡。一般来说,人们总是可以等待更长的时间来查看有哪些额外的数据到达,从而增加基于(更多)完整信息产生结果的机会。水印是这种权衡的技术表现。任何使用事件时间的流应用程序都必须产生水印,每个水印都用时间戳标记流中的一个点,并声明在该点上,流可能在该时间戳之前完成。

对于某些应用程序,快速生成可能正确的结果是可以的,事实上,这可能比等待更长的时间来生成更可能正确的结果要好。但在其他应用程序中,必须完全准确(无论这意味着什么,准确)。

确切地说,您应该做的不是技术问题,而是业务流程问题。最终,这取决于对帐后的陈述对您的业务意味着什么。也许您应该旨在重现当前任何流程的语义。

话虽如此,Flink 提供了一组工具,您可以结合使用以多种方式解决此用例,具体取决于您希望它如何工作的细节。以下是这些部分如何组合在一起:

每个语句都有一个end_time. 当事务流的水印达到 时end_time,这是人们可能认为该语句的事务聚合完成的第一个时刻。

这种水印将(通常)在指定交易流可能无序的数量界限的基础上完成。但是你要预料到,无论你多么悲观,一些异常交易都会违反这个假设,并且相对于水印来说是迟到的。

为了适应这种情况,您可以增加水印延迟以尝试覆盖所有可能的延迟(人们可能会争辩说,这通常是不可能的),或者决定在某些时候您必须继续并产生一个声称已和解的声明,但这实际上可能需要在未来进行更新或修正。这个任意延迟的问题是否是一个真正的问题(因为它可能是在银行中,一些国际交易可能会经历很长时间的延迟),或者仅仅是理论上的,取决于您的实际用例。

能够容纳延迟事务将要求您(1)将语句数据保留在 Flink 的托管状态中,以便添加延迟事务,然后可用于更新语句,或者(2)处理延迟事件以一种特殊的方式,通过从数据库中读取先前生成的结果,然后更新数据库中的记录(这需要以事务方式完成)。方法 #2 可以在一个单独的作业中实现,该作业消耗第一个作业产生的延迟事务流。

您可以通过在语句中包含时间戳来定义解决此问题的方法,该时间戳指定该语句准确地包含在该时间点之前已处理的那些事务。

于 2020-01-13T14:52:48.317 回答