簡體   English   中英

如何刪除滑動窗口中的重復項 - Apache Beam

[英]How to remove duplicates in sliding window - Apache Beam

我已經實現了一個具有多個無限源和側輸入的數據管道,將數據與滑動窗口(30 秒和每 10 秒)連接起來,並將轉換后的輸出發送到 Kafka 主題中。 我遇到的問題是,在窗口的前 10 秒內接收到的數據會發出 3 次(即)每當新窗口啟動時觸發,直到第一個窗口完成。 如何只發出一次轉換后的數據或避免重復?

我已經使用了廢棄的燒制窗格,它沒有任何區別。 每當我嘗試將窗口關閉行為設置為 FIRE_ALWAYS/FIRE_IF_NON_EMPTY 時,它都會引發以下錯誤。

線程“main” org.apache.beam.sdk.Pipeline$PipelineExecutionException 中的異常:java.lang.IllegalArgumentException:作為單例視圖訪問的空 PCollection。 考慮設置 withDefault 以在 org.apache.beam.runners.direct.DirectRunner$DirectPipelineResult.waitUntilFinish(DirectRunner.java:332) at org.apache.beam.runners.direct.DirectRunner$DirectPipelineResult.waitUntilFinish(DirectRunner. java:302) 在 org.apache.beam.runners.direct.DirectRunner.run(DirectRunner.java:197) 在 org.apache.beam.runners.direct.DirectRunner.run(DirectRunner.java:64) 在 org.apache .beam.sdk.Pipeline.run(Pipeline.java:313) at org.apache.beam.sdk.Pipeline.run(Pipeline.java:299) at y.yyy.main(yyy.java:86) 引起: java.lang.IllegalArgumentException:作為單例視圖訪問的空 PCollection。 考慮設置 withDefault 以在 org.apache.beam.sdk.transforms.View$SingletonCombineFn.identity(View.java:378) at org.apache.beam.sdk.transforms.Combine$BinaryCombineFn.extractOutput(Combine. java:481) 在 org.apache.beam.sdk.transforms.Combine$BinaryCombineFn.extractOutput(Combine.java:429) 在 org.apache.beam.sdk.transforms.Combine$CombineFn.apply(Combine.java:387)在 org.apache.beam.sdk.transforms.Combine$GroupedValues$1.processElement(Combine.java:2089)

data.apply("Transform", ParDo.of(
  new DoFn<String, Row>() {

    private static final long serialVersionUID = 1L;

    @ProcessElement
    public void processElement(
      ProcessContext processContext,
      final OutputReceiver<Row> emitter) {

        String record = processContext.element();
        final String[] parts = record.split(",");
        emitter.output(Row.withSchema(sch).addValues(parts).build());
    }
  })).apply(
    "window1",
    Window
      .<Row>into(
        SlidingWindows
          .of(Duration.standardSeconds(30))
          .every(Duration.standardSeconds(10)))
      .withAllowedLateness(
        Duration.ZERO,
        Window.ClosingBehavior.FIRE_IF_NON_EMPTY)
  .discardingFiredPanes());

請指導我只觸發一次窗口(即)我不想發送已經處理的記錄

更新:Side Input 的上述錯誤經常發生並且不是因為 Windows,這似乎是 Apache Beam 中的一個問題 ( https://issues.apache.org/jira/browse/BEAM-6086 )

我嘗試使用 State 來識別一行是否已經被處理,但狀態沒有被保留或被設置。 (即)我在閱讀狀態時總是為空。

public class CheckState extends DoFn<KV<String,String>,KV<Integer,String>> {
  private static final long serialVersionUID = 1L;

  @StateId("count")
  private final StateSpec<ValueState<String>> countState =
                     StateSpecs.value(StringUtf8Coder.of());

  @ProcessElement
  public void processElement(
    ProcessContext processContext,
    @StateId("count") ValueState<String> countState) {

        KV<String,String> record = processContext.element();
        String row = record.getValue();
        System.out.println("State: " + countState.read());
        System.out.println("Setting state as "+ record.getKey() + " for value"+ row.split(",")[0]);
        processContext.output(KV.of(current, row));
        countState.write(record.getKey());
    }

如果我正確理解了這個問題,它可能與管道中滑動窗口的使用有關:

滑動時間窗口重疊,來自 Beam guides Window Functions 的很好解釋

因為多個窗口重疊,數據集中的大多數元素將屬於多個窗口。這種窗口化對於獲取數據的運行平均值很有用;......

但是固定窗口不會重疊:

“固定的時間窗口代表數據流中一致的持續時間、非重疊的時間間隔..”

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM