连接流中2个流之一的饥饿

时间:2019-03-07 08:13:54

标签: apache-flink flink-streaming

背景

我们有2个流,我们称它们为AB。 它们分别产生元素ab

A产生元素的速度很慢(每分钟一个)。

B每2周接收一次单个元素。它使用flatMap函数,该函数接收此元素并在循环中生成约200万个b元素:

(Java)

for (BElement value : valuesList) {
    out.collect(updatedTileMapVersion);
}

此处的valueList包含约200万个b元素

我们使用A连接这些流(Bconnect),通过某个键进行键操作,并在连接的流上执行另一个flatMap

streamA.connect(streamB).keyBy(AClass::someKey, BClass::someKey).flatMap(processConnectedStreams)

每个b元素都有一个不同的密钥,这意味着有约200万个密钥来自B流。

问题

我们看到的是饥饿。即使有a个元素已准备好进行处理,它们也不会在processConnectedStreams中进行处理。

我们试图解决问题

我们尝试通过每10个元素执行一次B,在1秒内将流Thread.sleep()限制为10个元素:

long totalSent = 0;
for (BElement value : valuesList) {
    totalSent++;
    out.collect(updatedTileMapVersion);
    if (totalSent % 10 == 0) {
        Thread.sleep(1000)
    }
}

模拟processConnectedStreams与另一个Thread.sleep()花费1秒钟,我们尝试使用: *对所有管道设置10的并行度-不起作用 *为所有管道设置15的并行度-确实有效

问题

我们不希望使用所有这些资源,因为流B很少被激活,而对于流A来说,具有高度并行性的元素就显得过分了。 是否可以在不将并行度设置为超过我们每秒发送的b个元素的数量的情况下解决它?

1 个答案:

答案 0 :(得分:0)

如果您共享完整的工作流拓扑,这将很有用。例如,您没有提及对数据进行任何键控或随机分区。如果真是这样,那么Flink将在一项任务中管线化多个操作,这可能(取决于拓扑结构)导致您遇到的问题。

如果是这种情况,那么在processConnectedStreams之前强制分区会有所帮助,因为该操作将从网络缓冲区读取。