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

Hadoop 使用S3AFileSystem的Flink不会从S3读取子文件夹,hadoop,amazon-s3,apache-flink,flink-streaming,Hadoop,Amazon S3,Apache Flink,Flink Streaming,我们正在使用Flink 1.2.0和建议的S3AFileSystem配置。当一个简单的流作业的源是S3存储桶中的一个文件夹时,它会按预期工作 当作业的源是一个本身包含子文件夹的文件夹时,该作业运行时不会出错,但不会产生输出 为清楚起见,下面是S3铲斗的模型。运行作业以指向s3a://bucket/folder/2017/04/25/01/可以正确读取所有三个对象以及bucket中出现的任何后续对象。将作业指向s3a://bucket/folder/2017/(或任何其他中间文件夹)将导致作业运行

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

当作业的源是一个本身包含子文件夹的文件夹时,该作业运行时不会出错,但不会产生输出

为清楚起见,下面是S3铲斗的模型。运行作业以指向
s3a://bucket/folder/2017/04/25/01/
可以正确读取所有三个对象以及bucket中出现的任何后续对象。将作业指向
s3a://bucket/folder/2017/
(或任何其他中间文件夹)将导致作业运行时不产生任何结果

在绝望中,我们尝试了[例如]包括尾随
/
的排列

.
`-- 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>

fs.s3a.impl
org.apache.hadoop.fs.s3a.S3AFileSystem
fs.s3a.buffer.dir
/tmp
我们已包括此处列出的S3AFileSystem的所有JAR:

我们被难住了。这似乎应该奏效;互联网上有大量的面包屑表明这确实有效。[例如:


帮帮我,松鼠们……你们是我唯一的希望!

这是什么版本的Hadoop

如果这在Hadoop 2.8中停止了,可能是一种回归,这意味着可能是我的错。首先在FLINK下提交一个JIRA@文件,然后,如果它在2.8.0中是新的,则将其链接为Hadoop-13208

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


这个大的
listFiles()
更改将路径下的文件枚举从递归树遍历移动到路径下所有子项的一系列平面列表:它对其他所有内容都非常有效(distcp、tests、hive、spark)并且自2016年12月以来一直在运送产品;如果这是原因,我会有点惊讶,但我不否认这是错误的。很抱歉,在上面的帮助下回答我自己的问题

在Flink中,当使用时,
FileInputFormat
默认情况下不会

无论源代码是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")

}

与flink 1.7.x版一样,flink提供了两个文件系统来与Amazon S3对话,
flink-S3-fs-presto
flink-S3-fs-hadoop
flink-S3-fs-hadoop
flink-S3-fs-presto
使用
S3:///code>方案注册URI的默认文件系统包装器,
flink-S3-fs-hadoop>还为
s3a://
注册,并且
flink-s3-fs-presto
也为
s3p://
注册,因此您可以使用此功能同时使用这两个功能

示例代码:

//Reading Data from S3
// This will print all the contents in the bucket line wise
final Path directory = new Path("s3a://husnain28may2020/");
final FileSystem fs = directory.getFileSystem();

//using input format
org.apache.flink.api.java.io.TextInputFormat textInputFormatS3 = new org.apache.flink.api.java.io.TextInputFormat(directory);
DataSet<String> linesS3 = env.createInput(textInputFormatS3);
linesS3.print();
//从S3读取数据
//这将按行打印铲斗中的所有内容
最终路径目录=新路径(“s3a://husnain28may2020/”;
final FileSystem fs=directory.getFileSystem();
//使用输入格式
org.apache.flink.api.java.io.TextInputFormat textInputFormatS3=新org.apache.flink.api.java.io.TextInputFormat(目录);
数据集linesS3=env.createInput(textInputFormatS3);
linesS3.print();

可能是我忘记添加的相关项目…表示对版本2.8.0中S3A列表文件的更改。Flink文档建议使用
hadoop-aws-2.7.2.jar
。最初,这是Flink 1.2.0/Scala 2.11/hadoop 2.7.0,添加了hadoop-aws-2.7.2.jar(根据Flink文档)。它是“工厂”之一从Flink网站下载选项。此后,我尝试改变Hadoop版本和/或Hadoop-aws.jar版本,并在本地构建。我已经升级到2.8.0和2.6.0,但都没有成功。我曾希望升级到Hadoop 2.8.0会解决这个问题,但Flink 1.2.0似乎无法很好地使用该版本的Hadoop。Flink master I如果它在Hadoop 2.7中,那么它就不是新的列表。为什么不看看它是在本地工作(文件://))还是hdfs…如果它在那里工作,而不是在s3a上,那么s3a就是(不是)当然,做是可能的原因!首先检查明显的事情。我将在下面回答我自己的问题。这与s3a无关,一切都与微妙的Flink选项有关。感谢您的帮助和耐心。