Scio Apache Beam-如何正确分隔管道代码?

时间:2019-08-25 06:28:23

标签: scala apache-beam spotify-scio

我有一个带有一组PTransforms的管道,并且我的方法越来越长。

我想在单独的程序包中编写我的DoFns和复合转换,并在我的main方法中重新使用它们。使用python非常简单,如何使用Scio来实现呢?我看不到这样做的任何例子。 :(

     withFixedWindows(
        FIXED_WINDOW_DURATION,
        options = WindowOptions(
          trigger = groupedWithinTrigger,
          timestampCombiner = TimestampCombiner.END_OF_WINDOW,
          accumulationMode = AccumulationMode.ACCUMULATING_FIRED_PANES,
          allowedLateness = Duration.ZERO
        )
      )
      .sumByKey
      // How to write this in an another file and use it here?
      .transform("Format Output") {
        _
          .withWindow[IntervalWindow]
          .withTimestamp
      }

3 个答案:

答案 0 :(得分:1)

您可以使用map函数来映射元素example

您可以传递另一个类的方法引用,而不是传递lambda 示例.map(MyClass.MyFunction)

答案 1 :(得分:1)

如果我正确理解了您的问题,则希望将map, groupBy, ...转换捆绑在单独的程序包中,并在主管道中使用它们。

一种方法是使用applyTransform,但是最终您将使用不兼容Scala的PTransforms。

您可以简单地编写一个接收SCollection并返回转换后的函数的函数,例如:

def myTransform(input: SCollection[InputType]): Scollection[OutputType] = ???

但是,如果您打算编写自己的Source / Sink,请查看ScioIO class

答案 2 :(得分:1)

我认为解决此问题的一种方法可能是在另一个包中定义一个对象,然后在该对象中创建一个具有转换所需逻辑的方法。例如:

def main(cmdlineArgs: Array[String]): Unit = {
    val (sc, args) = ContextAndArgs(cmdlineArgs)

    val defaulTopic = "tweets"
    val input = args.getOrElse("inputTopic", defaulTopic)
    val output = args("outputTopic")

    val inputStream: SCollection[Tweet] = sc.withName("read from pub sub").pubsubTopic(input)
      .withName("map to tweet class").map(x => {parse(x).extract[Tweet]})

    inputStream
      .flatMap(sentiment.predict) // object sentiment with method predict

  }
object sentiment  {

  def predict(tweet: Tweet): Option[List[TweetSentiment]] = {
    val data = tweet.text
    val emptyCase = Some("")
    Some(data) match {
      case `emptyCase` => None
      case Some(v) => Some(entitySentimentFile(data)) // I used another method, //not defined
    }

  }

也请通过此链接获取Scio examples

中给出的示例