Scala 在Flink'中连续处理拼花地板文件作为数据流;s数据流API
我在HDFS上有一个拼花文件。它每天都会被一个新的覆盖。我的目标是使用DataStream API在Flink作业中以DataStream的形式连续地发出这个拼花地板文件,当它发生变化时。 最终目标是在广播状态下使用文件内容,但这超出了这个问题的范围Scala 在Flink'中连续处理拼花地板文件作为数据流;s数据流API,scala,apache-flink,parquet,Scala,Apache Flink,Parquet,我在HDFS上有一个拼花文件。它每天都会被一个新的覆盖。我的目标是使用DataStream API在Flink作业中以DataStream的形式连续地发出这个拼花地板文件,当它发生变化时。 最终目标是在广播状态下使用文件内容,但这超出了这个问题的范围 要连续处理文件,有一个非常有用的API:about datasources。更具体地说,文件处理模式。连续处理:这正是我需要的。这适用于读取/监视文本文件,没有问题,但不适用于拼花地板文件: 要处理拼花文件,我可以使用以下API使用Hadoop输入
我想以某种方式结合这两个API,通过DataStream API连续处理拼花地板文件。你们中有人试过类似的方法吗?浏览完Flink的代码后,看起来这两个API相对不同,似乎不可能将它们合并在一起 另一种方法(我将在这里详细介绍)是定义自己的SourceFunction,它将定期读取文件:
class ParquetSourceFunction extends SourceFunction[Int] {
private var isRunning = true
override def run(ctx: SourceFunction.SourceContext[Int]): Unit = {
while (isRunning) {
val path = new Path("path_to_parquet_file")
val conf = new Configuration()
val readFooter = ParquetFileReader.readFooter(conf, path, ParquetMetadataConverter.NO_FILTER)
val metadata = readFooter.getFileMetaData
val schema = metadata.getSchema
val parquetFileReader = new ParquetFileReader(conf, metadata, path, readFooter.getBlocks, schema.getColumns)
var pages: PageReadStore = null
try {
while ({ pages = parquetFileReader.readNextRowGroup; pages != null }) {
val rows = pages.getRowCount
val columnIO = new ColumnIOFactory().getColumnIO(schema)
val recordReader = columnIO.getRecordReader(pages, new GroupRecordConverter(schema))
(0L until rows).foreach { _ =>
val group = recordReader.read()
val my_integer = group.getInteger("field_name", 0)
ctx.collect(my_integer)
}
}
}
// do whatever logic suits you to stop "watching" the file
Thread.sleep(60000)
}
}
override def cancel(): Unit = isRunning = false
}
然后,使用streamExecutionEnvironment注册此源:
val dataStream: DataStream[Int] = streamExecutionEnvironment.addSource(new ParquetProtoSourceFunction)
// do what you want with your new datastream
class ParquetSourceFunction extends SourceFunction[Int] {
private var isRunning = true
override def run(ctx: SourceFunction.SourceContext[Int]): Unit = {
while (isRunning) {
val path = new Path("path_to_parquet_file")
val conf = new Configuration()
val readFooter = ParquetFileReader.readFooter(conf, path, ParquetMetadataConverter.NO_FILTER)
val metadata = readFooter.getFileMetaData
val schema = metadata.getSchema
val parquetFileReader = new ParquetFileReader(conf, metadata, path, readFooter.getBlocks, schema.getColumns)
var pages: PageReadStore = null
try {
while ({ pages = parquetFileReader.readNextRowGroup; pages != null }) {
val rows = pages.getRowCount
val columnIO = new ColumnIOFactory().getColumnIO(schema)
val recordReader = columnIO.getRecordReader(pages, new GroupRecordConverter(schema))
(0L until rows).foreach { _ =>
val group = recordReader.read()
val my_integer = group.getInteger("field_name", 0)
ctx.collect(my_integer)
}
}
}
// do whatever logic suits you to stop "watching" the file
Thread.sleep(60000)
}
}
override def cancel(): Unit = isRunning = false
}
val dataStream: DataStream[Int] = streamExecutionEnvironment.addSource(new ParquetProtoSourceFunction)
// do what you want with your new datastream