流式传输到对flink 1.6.1不满意的拼花文件

时间:2018-10-04 02:38:58

标签: apache-flink

我对flink(以及镶木地板/硬纸板)非常陌生,因此我肯定在做一些非常愚蠢的事情。我正在尝试创建一个接收器,该接收器会将我的数据源转储到Parquet文件中。

我的代码如下:

val streamEnv = StreamExecutionEnvironment.getExecutionEnvironment
streamEnv.setParallelism(1);
streamEnv.enableCheckpointing(100, CheckpointingMode.EXACTLY_ONCE);
val sink = StreamingFileSink.forBulkFormat(outputPath, ParquetAvroWriters.forReflectRecord(classOf[MyClass])).build()
testSource.addSink(sink)

不幸的是,我没有收到以前的异常,但是它仍然无法生成正确的输出。我目前正在获取其中包含4B数据的单个.part-xxx文件。此流中大约有20,000条记录,因此似乎不正确。

在开始编写此问题之前,我从ParquetAvroWriters.java的第84行获取了一个方法未发现异常。该代码如下:

    return AvroParquetWriter.<T>builder(out)
            .withSchema(schema)
            .withDataModel(dataModel)
            .build();

AvroParquetWriter方法签名是:

  public static <T> Builder<T> builder(Path file)

但是在ParquetAvroWriters.java调用时的参数是StreamOutputFile,因此没有方法错误。

我正在使用链接1.6.1和parquet-hadoop / parquet-avro 1.10.0。我应该如何精确地设置内容以编写实木复合地板文件?这令人感到最沮丧-我什至找不到一个可以编译的示例。任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:3)

在阅读了人们的评论之后,我用相同的代码(类似)创建了一个项目,但是您可以编译和执行。

object CustomSource {

 case class TextOut(data:String )

 def generateRandomStringSource(out: SourceContext[TextOut]) = {
   val lines = Array("how are you", "you are how", " i am fine")
   while (true) {
    val index = Random.nextInt(3)
    Thread.sleep(200)
    out.collect(TextOut(lines(index)))
  }
}


def main(args: Array[String]) {

  val streamEnv = 
  StreamExecutionEnvironment.getExecutionEnvironment

  streamEnv.setParallelism(1)
  streamEnv.enableCheckpointing(10000, 
  CheckpointingMode.EXACTLY_ONCE)
  val sink = StreamingFileSink.forBulkFormat(new 
    Path("file:///tmp/test2"),
   ParquetAvroWriters.forReflectRecord(classOf[TextOut])).build()

  val customSource = streamEnv.addSource(generateRandomStringSource 
  _)

  customSource.print()

   customSource.addSink(sink)




   streamEnv.execute()

 }

}

我创建了一个项目来展示运行方式以及所需的最少内容(罐子,ect)。

这是链接:https://github.com/jose1003/flinkparquet

BR

乔斯

答案 1 :(得分:2)

Flink的StreamingFileSink使用批量格式会自动使用OnCheckpointRollingPolicy。这意味着仅在检查点完成时才会实现结果。要求提供恰好一次的处理保证。

我假设您使用CollectionSource作为测试输入,并且处理此输入所需的时间少于指定的100ms。因此,没有检查点可以完成,也不会写入任何结果。输入完全消耗完后,Flink不会触发检查点。因此,最后一个完成的检查点之后的所有事件将都不可见。

尝试减小检查点间隔,增加CollectionSource中的元素数量,或者编写自己的TestingSource extends SourceFunction,其运行时间至少与单个检查点间隔(例如,睡眠)一样长。这样,Flink应该能够完成一个检查点,并将结果写到指定的目录中。