簡體   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