使用S3AFileSystem的Flink不会从S3读取子文件夹

时间:2017-04-27 04:49:09

标签: hadoop amazon-s3 apache-flink flink-streaming

我们正在使用Flink 1.2.0和建议的S3AFileSystem配置。当源是S3存储桶中的单个文件夹时,简单的流式传输作业按预期工作。

作业运行没有错误 - 但生成输出 - 当其源是一个本身包含子文件夹的文件夹时。

为清楚起见,下面是S3存储桶的模型。运行作业以指向s3a://bucket/folder/2017/04/25/01/正确读取存储在存储桶中的所有三个对象和后续对象。将作业指向s3a://bucket/folder/2017/(或任何其他中间文件夹)会导致作业无法生成任何内容。

在绝望的情况下,我们尝试了[in | ex]包含尾随/的排列。

.
`-- folder
    `-- 2017
        `-- 04
            |-- 25
            |   |-- 00
            |   |   |-- a.txt
            |   |   `-- b.txt
            |   `-- 01
            |       |-- c.txt
            |       |-- d.txt
            |       `-- e.txt
            `-- 26

工作代码:

def main(args: Array[String]) {

  val parameters = ParameterTool.fromArgs(args)
  val bucket = parameters.get("bucket")
  val folder = parameters.get("folder")

  val path = s"s3a://$bucket/$folder"

  val env = StreamExecutionEnvironment.getExecutionEnvironment

  val lines: DataStream[String] = env.readFile(
    inputFormat = new TextInputFormat(new Path(path)),
    filePath = path,
    watchType = FileProcessingMode.PROCESS_CONTINUOUSLY,
    interval = Time.seconds(10).toMilliseconds)

  lines.print()
  env.execute("Flink Streaming Scala API Skeleton")
}

core-site.xml是根据文档配置的:

<configuration>
  <property>
    <name>fs.s3a.impl</name>
    <value>org.apache.hadoop.fs.s3a.S3AFileSystem</value>
  </property>
  <property>
    <name>fs.s3a.buffer.dir</name>
    <value>/tmp</value>
  </property>
</configuration>

我们已经包含了此处列出的所有S3AFileSystem jar:https://ci.apache.org/projects/flink/flink-docs-release-1.2/setup/aws.html#flink-for-hadoop-27

我们很难过。这似乎应该有效;互联网上有很多面包屑表明这个做了工作。 [例如,http://apache-flink-user-mailing-list-archive.2336050.n4.nabble.com/Reading-files-from-an-S3-folder-td10281.html]

帮助我,松鼠......你是我唯一的希望!

3 个答案:

答案 0 :(得分:6)

在上面Steve Loughran的帮助下回答我自己的问题。

在Flink中,使用file-based data source to process continuously时,默认情况下FileInputFormat enumerate nested files

无论源是S3还是其他任何东西都是如此。

你必须这样设置:

def main(args: Array[String]) {

  val parameters = ParameterTool.fromArgs(args)
  val bucket = parameters.get("bucket")
  val folder = parameters.get("folder")

  val path = s"s3a://$bucket/$folder"

  val env = StreamExecutionEnvironment.getExecutionEnvironment

  val textInputFormat = new TextInputFormat(new Path(path))

  //this is important!
  textInputFormat.setNestedFileEnumeration(true)

  val lines: DataStream[String] = env.readFile(
    inputFormat = textInputFormat,
    filePath = path,
    watchType = FileProcessingMode.PROCESS_CONTINUOUSLY,
    interval = Time.seconds(10).toMilliseconds)

  lines.print()
  env.execute("Flink Streaming Scala API Skeleton")

}

答案 1 :(得分:0)

这是什么版本的Hadoop?

如果使用Hadoop 2.8停止运行,可能是回归,这可能是我的错。首先在FLINK下提交一个JIRA @ issues.apache.org,然后,如果它在2.8.0中的新内容将其链接为HADOOP-13208

这里的代码片段是一个很好的例子,可以用于回归测试,是时候我为Flink做了一些。

那个大的listFiles()更改会将路径下的文件枚举从递归树形路径移动到路径下所有子条目的一系列平面列表:它可以很好地用于其他所有内容(distcp,tests,hive,火花)并且自12月16日以来一直在产品中运输;如果是原因,我会感到有些惊讶,但不会否认责任。遗憾

答案 2 :(得分:0)

与flink 1.7.x版本一样,Flink提供了两个文件系统来与Amazon S3进行通信,flink-s3-fs-prestoflink-s3-fs-hadoopflink-s3-fs-hadoopflink-s3-fs-presto都使用s3://方案注册URI的默认文件系统包装器,flink-s3-fs-hadoop也注册s3a://flink-s3-fs-presto也注册{ {1}},因此您可以使用它同时使用两者。

示例代码:

s3p://