在Apache Beam中使用defaultNaming进行动态窗口写入

时间:2018-05-07 23:54:01

标签: java google-cloud-dataflow apache-beam apache-beam-io

我一直在回答this postthe documentation,以便在管道末端对我的数据执行动态窗口化写入。以下是我到目前为止的情况:

static void applyWindowedWrite(PCollection<String> stream) {
    stream.apply(
        FileIO.<String, String>writeDynamic()
            .by(Event::getKey)
            .via(TextIO.sink())
            .to("gs://some_bucket/events/")
            .withNaming(key -> defaultNaming(key, ".json")));
}

但NetBeans警告我最后一行语法错误:

FileNaming is not public in Write; cannot be accessed outside package

如何使defaultNaming可用于我的管道,以便我可以将其用于动态写入。或者,如果那是不可能的,我应该做什么呢?

1 个答案:

答案 0 :(得分:4)

发布我想出的以防其他人遇到此事。

我之前尝试使用writeDynamic()的方式有三个问题。

  1. 以前我一直在使用Beam版本2.3.0,它确实将FileNaming描述为FileIO.Write的内部类。 Beam 2.4.0将FileNaming定义为public static interface,使其在外部可用。
  2. 完全解析/导入defaultNaming。而不是直接调用defaultNaming - 正如示例文档中所调用的那样 - 它必须作为FileIO.Write.defaultNaming调用,因为FileIO是我实际导入的包。
  3. 执行动态写入也需要添加withDestinationCoder
  4. 最终解决方案最终看起来像这样。

    static void applyWindowedWrite(PCollection<String> stream) {
        stream.apply(FileIO.<String, String>writeDynamic()
                    .by(Event::getKey)
                    .via(TextIO.sink())
                    .to("gs://some_bucket/events/")
                    .withDestinationCoder(StringUtf8Coder.of())
                    .withNumShards(1)
                    .withNaming(key -> FileIO.Write.defaultNaming(key, ".json")));
    }
    

    其中Event::getKey是在具有签名public static String getKey(String event)的同一个包中定义的静态函数。

    执行窗口写入,每个窗口写入一个文件(由.withNumShards(1)方法定义)。这假设窗口已在上一步中定义。在写入之前不需要GroupByKey,因为只要明确定义了分片数,它就会在写入过程中完成。有关详细信息,请参阅FileIO documentation&#34;撰写文件 - &gt;每个窗格生成多少个分片&#34;。