在Flink中以(X,Y)为键的缓慢流丰富了由(X)为键的缓慢变化的流

问题描述 投票:1回答:1

我需要用(userId)为键的缓慢变化的streamA来充实以(userId,startTripTimestamp)为键的快速变化的streamB

我将Flink 1.8与DataStream API结合使用。我考虑2种方法:

  1. Broadcast streamB,并通过userId和最近的时间戳加入流。它等同于TableAPI中的DynamicTable吗?我可以看到此解决方案的一些缺点:streamB需要适合每个工作程序节点的RAM,因为整个streamB需要存储在每个工作程序的RAM中,所以它增加了RAM的利用率。

  2. streamA的通用状态,以仅(userId)作为键的流,我们将其命名为streamC,以便具有与streamB的公共密钥。然后,我可以将streamCstreamB合并,按处理时间排序,并在状态下处理两种类型的事件。处理一般的流(过程函数中的更多代码)更为复杂,但不会消耗太多的RAM来在所有节点上拥有所有streamB。他们在此解决方案中还有其他弊端吗?

我也看到了这个建议https://cwiki.apache.org/confluence/display/FLINK/FLIP-17+Side+Inputs+for+DataStream+API,它说:

[通常,大多数遵循加入主流的模式一个或多个缓慢变化的输入或静态数据:

[...]

加入具有缓慢发展的数据流:这与上述情况,但我们用于充实的侧输入是随着时间的推移而发展。这可以通过等待一些初始数据来完成在处理主输入和连续输入之前可用将新数据吸收到内部输入结构中到达。

[不幸的是,要达到此功能https://issues.apache.org/jira/browse/FLINK-6131似乎需要很长的时间,并且没有其他描述。因此,我想问一下针对所描述用例的当前推荐方法。

我见过Combining low-latency streams with multiple meta-data streams in Flink (enrichment),但没有指定该流的键,而且在Flink 1.4时已得到回答,因此我希望推荐的解决方案可能已更改。

apache-flink flink-streaming
1个回答
0
投票

答案取决于您需要使用的streamB状态的大小来丰富streamA

  • 如果广播了streamB状态,则将所有用户ID从streamB传递到每个任务管理器。任务管理器上的每个任务将仅具有来自streamA的这些用户ID的子集。因此,streamB中的某些userId数据将永远不会使用,并且会浪费。因此,如果您认为streamB状态的大小不足以真正影响您的工作,并且不占用大量内存来为状态管理留下更少的内存,则可以保留整个streamB状态。这是你的#1。
  • 如果您的streamB状态确实很大并且会占用任务管理器的大量内存,则应考虑方法2。通过相同的ID标识两个流,以确保具有相同userID的元素完成相同的任务,然后可以使用托管状态来维护每个密钥streamB状态,并使用此托管状态来丰富streamA元素。
© www.soinside.com 2019 - 2024. All rights reserved.