繁体   English   中英

Flink (1.3.2) 只向每个算子广播记录一次

[英]Flink (1.3.2) Broadcast record to every operator exactly once

我有一个很像这样的执行图:

{"nodes":[{"id":1,"type":"Source: AggregatedData","pact":"Data Source","contents":"Source: AggregatedData","parallelism":1},{"id":2,"type":"AddVirtualKeyFunction","pact":"Operator","contents":"AddVirtualKeyFunction","parallelism":4,"predecessors":[{"id":1,"ship_strategy":"REBALANCE","side":"second"}]},{"id":3,"type":"Source: FilterInformation","pact":"Data Source","contents":"Source: FilterInformation","parallelism":1},{"id":4,"type":"BroadcastFilterInformation","pact":"Operator","contents":"BroadcastFilterInformation","parallelism":1,"predecessors":[{"id":3,"ship_strategy":"FORWARD","side":"second"}]},{"id":7,"type":"ConnectAndApplyFilterFunction","pact":"Operator","contents":"ConnectAndApplyFilterFunction","parallelism":4,"predecessors":[{"id":2,"ship_strategy":"HASH","side":"second"},{"id":4,"ship_strategy":"HASH","side":"second"}]},{"id":8,"type":"Sink: OutputFilteredData","pact":"Data Sink","contents":"Sink: OutputFilteredData","parallelism":4,"predecessors":[{"id":7,"ship_strategy":"FORWARD","side":"second"}]}]}

(可以在这里可视化: https : //flink.apache.org/visualizer/

我有一个聚合数据流(“AggregatedData”,ID = 1),它需要被来自另一个流(“FilterInformation”,ID = 3)的某个过滤器过滤。

我首先做的是在我的“ConnectAndApplyFilterFunction”(ID = 7)中使用操作符状态,它在技术上工作正常,但仅限于 1 的并行度。

目前,我正在做一些 hack:在“AddVirtualKeyFunction”中,我将聚合数据映射到Tuple2<Integer, AggregatedData> ,其中 Integer (f0) 是从 0 到 19 的随机生成的数字:

@Override
public Tuple2<Integer, AggregatedData> map(AggregatedData value) throws Exception {
    return new Tuple2<>(ThreadLocalRandom.current().nextInt(this.virtualKeyCount), value);
}

“BroadcastFilterInformation”是一个 flatMap,它在每次收到新的 FilterInformation 时发布Tuple2<Integer, FilterInfo> 20 次(f0 0-19):

@Override
public void flatMap(FilterInfo filterInfo, Collector<Tuple2<Integer, FilterInfo>> collector) throws Exception {
    if (this.currentLatestTimestamp < filterInfo.getLastUpdateTime()) {
        this.currentLatestTimestamp = filterInfo.getLastUpdateTime();

        for (int i = 0; i < this.broadcastCount; i++) {
            collector.collect(new Tuple2<>(i, filterInfo));
        }
    }
}

我现在连接两个流并通过它们的“虚拟密钥”( Tuple2.f0 )对它们进行Tuple2.f0 我在“ConnectAndapplyFilterFunction”(ID = 7)中保留了 20 个处于键控状态的FilterInfo副本。

工作正常,我可以在我的主要路径上使用并行性。 但是为什么我使用 20 个“虚拟键”而我的并行度只有 4 个? 因为只有 4 个键,并不是所有的操作符都会被使用(在我的测试中,2 个操作符没有接收到任何数据)。

有什么方法可以从一个流中广播一些数据,以便另一端的每个操作员都能收到自己的副本?

您最有可能使用broadcast选项使数据可用于操作中的其他实例。

批处理的情况下,您可以使用广播变量,根据链接的网站描述如下,也可以在那里找到相应的示例:

除了操作的常规输入之外,广播变量允许您使数据集可用于操作的所有并行实例。 这对于辅助数据集或数据相关参数化很有用。 然后操作员可以访问该数据集作为集合。

流处理的情况下,您可以添加datastream.broadcast()以将datastream.broadcast()广播到另一个。

根据flink 网站- 广播功能 - 将元素(从一个流)广播到每个分区。

在流处理场景中,您需要提醒自己您需要考虑竞争条件,因为来自任一流的数据可以以任何顺序出现。

可以在此处查看示例代码

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM