Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 每X封来自Pubsub的消息写入云存储_Java_Google Cloud Dataflow_Apache Beam_Google Cloud Pubsub - Fatal编程技术网

Java 每X封来自Pubsub的消息写入云存储

Java 每X封来自Pubsub的消息写入云存储,java,google-cloud-dataflow,apache-beam,google-cloud-pubsub,Java,Google Cloud Dataflow,Apache Beam,Google Cloud Pubsub,我对CloudDataflow/ApacheBeam还不熟悉,所以这个概念/编程对我来说仍然很模糊 我想做的是,Dataflow侦听Pubsub并获取JSON格式的消息: { "productId": "...", "productName": "..." } 并将其转化为: { "productId": "...", "productName": "...", "sku": "...", "inventory": { "revenue": <some D

我对CloudDataflow/ApacheBeam还不熟悉,所以这个概念/编程对我来说仍然很模糊

我想做的是,Dataflow侦听Pubsub并获取JSON格式的消息:

{
  "productId": "...",
  "productName": "..."
}
并将其转化为:

{
  "productId": "...",
  "productName": "...",
  "sku": "...",
  "inventory": {
    "revenue": <some Double>,
    "stocks":  <some Integer>
  }
}
请填写缺少的部分,并告诉我有关窗口设置的提示(例如,什么是适当的配置等),以及我应该在哪些步骤中插入/应用它。

  • 我认为您不需要在
    IngestFromPubsub
    EnricDataFromAPI
    中使用任何窗口。窗口化的目的是将时间上相邻的记录分组到窗口中,以便可以对它们进行聚合计算。但是,由于您不进行任何聚合计算,并且对独立处理每条记录感兴趣,因此不需要windows

  • 由于您总是将一个输入记录转换为一个输出记录,因此
    EnricDataFromAPI
    应该是一个。这将使代码更容易编写

  • 在ApacheBean Java中处理JSON有很多资源:

  • 您不必使用Jackson将JSON映射到Java对象。您可以直接操作JSON。您可以使用Java来解析/操作/序列化

      • 我认为您不需要在
        IngestFromPubsub
        EnricDataFromAPI
        中使用任何窗口。窗口化的目的是将时间上相邻的记录分组到窗口中,以便可以对它们进行聚合计算。但是,由于您不进行任何聚合计算,并且对独立处理每条记录感兴趣,因此不需要windows

      • 由于您总是将一个输入记录转换为一个输出记录,因此
        EnricDataFromAPI
        应该是一个。这将使代码更容易编写

      • 在ApacheBean Java中处理JSON有很多资源:

      • 您不必使用Jackson将JSON映射到Java对象。您可以直接操作JSON。您可以使用Java来解析/操作/序列化


      如何获得
      sku
      值?它是否保留在源消息中,从Pub/Sub传递?就像从myapihost.com/api/products/获取一样简单。是的,
      sku
      会保留在原始消息中。在写入GCS时,您希望执行自定义批处理的原因是什么?Beam默认为您执行批处理。@MikhailGryzykhin最初,我只希望一条记录一次存储写入。最初我没有窗口设置,但当我尝试执行时,出现了一个运行时错误,说我需要窗口设置,因为
      option.setStreaming(true)
      。这很有意义,可能是因为它是一条无界流,Beam希望根据时间将记录组合在一起。我的问题更倾向于可能性。你如何获得
      sku
      价值?它是否保留在源消息中,从Pub/Sub传递?就像从myapihost.com/api/products/获取一样简单。是的,
      sku
      会保留在原始消息中。在写入GCS时,您希望执行自定义批处理的原因是什么?Beam默认为您执行批处理。@MikhailGryzykhin最初,我只希望一条记录一次存储写入。最初我没有窗口设置,但当我尝试执行时,出现了一个运行时错误,说我需要窗口设置,因为
      option.setStreaming(true)
      。这很有意义,可能是因为它是一条无界流,Beam希望根据时间将记录组合在一起。我的问题更多的是关于可能性的。这是我最初做的,没有窗口。但是,当我执行此操作时,出现一个运行时错误,该错误表示我需要打开窗口,因为
      option.setStreaming(true)
      。我现在不想为窗口设置而烦恼,因为我已经开始了解这一点了。您能将所有窗口设置移到
      EnricDataFromAPI
      WriteToGCS
      步骤之间吗?你还会有运行时错误吗?这是我删除窗口时得到的结果
      java.lang.IllegalArgumentException:在将writefile应用于无界PCollection时必须使用窗口写入
      我需要更多信息。哪一行抛出异常?异常是由
      EnricDataFromAPI
      WriteToGCS
      IngestFromPubsub
      引起的吗?您可以通过尝试或错误来确定这一点(从管道中删除一个步骤,重试,检查异常,将其放回,然后重复)。如果使用WindowedWrites删除
      ,会发生什么情况?
      您是否尝试将
      MapElements
      用于
      EnricDataFromAPI
      ?您是否尝试过在
      EnricDataFromAPI
      WriteToGCS
      之间添加窗口化步骤?我最初就是这么做的,没有窗口化。但是,当我执行此操作时,出现一个运行时错误,该错误表示我需要打开窗口,因为
      option.setStreaming(true)
      。我现在不想为窗口设置而烦恼,因为我已经开始了解这一点了。您能将所有窗口设置移到
      EnricDataFromAPI
      WriteToGCS
      步骤之间吗?你还会有运行时错误吗?这是我删除窗口时得到的结果
      java.lang.IllegalArgumentException:在将writefile应用于无界PCollection时必须使用窗口写入
      我需要更多信息。哪一行抛出异常?异常是由
      EnricDataFromAPI
      WriteToGCS
      IngestFromPubsub
      引起的吗?您可以通过尝试或错误来确定这一点(从管道中删除一个步骤,重试,检查异常,将其放回,然后重复)。如果使用WindowedWrites删除
      ,会发生什么情况?
      您是否尝试将
      MapElements
      用于
      EnricDataFromAPI
      ?您是否尝试过在
      EnricDataFromAPI
      WriteToGCS
      之间添加窗口步骤?
      public static void main(String[] args) {
      
          Options options = PipelineOptionsFactory.fromArgs(args).withValidation().as(Options.class);
          options.setStreaming(true);
      
          Pipeline pipeline = Pipeline.create(options);
          pipeline
              .apply("IngestFromPubsub", PubsubIO.readStrings().fromTopic(options.getTopic()))
              // I don't really understand the next part, I just copied from official documentation and filled in some values
              .apply(Window.<String>into(FixedWindows.of(Duration.millis(5000)))
                  .withAllowedLateness(Duration.millis(5000))
                  .triggering(AfterProcessingTime.pastFirstElementInPane().plusDelayOf(Duration.millis(1000)))
                  .discardingFiredPanes()
              )
              .apply("EnrichDataFromAPI", ParDo.of(
                  new DoFn<String, String>() {
                      @ProcessElement
                      public void processElement(ProcessContext c) {
                          c.element();
                          // help on this part, I heard I need to use Jackson but I don't know, for API HttpClient is sufficient
                          // ... deserialize, call API, serialize again ...
                          c.output(enrichedJSONString);
                      }
                  }
              ))
              .apply("WriteToGCS", 
                  TextIO.write().withWindowedWrites().withNumShards(1).to(options.getOutput()))
          ;
      
      
          PipelineResult result = pipeline.run();
      }