使用火花从HDFS读取时如何避免"Not a file"异常



在初始EMR步骤中,我使用S3DistCP将一个文件树从S3复制到HDFS。hdfs dfs -ls -R hdfs:///data_dir显示了预期的文件,看起来像:

/data_dir/year=2015/
/data_dir/year=2015/month=01/
/data_dir/year=2015/month=01/day=01/
/data_dir/year=2015/month=01/day=01/data01.12345678
/data_dir/year=2015/month=01/day=01/data02.12345678
/data_dir/year=2015/month=01/day=01/data03.12345678

"目录"被列为零字节文件。

然后我运行一个需要读取这些文件的spark步骤。加载代码如下:

sqlctx.read.json('hdfs:///data_dir, schema=schema)

作业失败,java异常

java.io.IOException: Not a file: hdfs://10.159.123.38:9000/data_dir/year=2015

我曾经(也许是天真地)假设spark会递归地下行'dir树'并加载数据文件。如果我指向S3,它会成功加载数据。

我误解HDFS了吗?我能告诉spark忽略零字节文件吗?我可以使用S3DistCp来平树吗?

在当前spark上下文的Hadoop配置中,为Hadoop InputFormat配置"递归"读取,以获取sql ctx

val hadoopConf = sparkCtx.hadoopConfiguration
hadoopConf.set("mapreduce.input.fileinputformat.input.dir.recursive", "true")

这将给出"not a file"的解决方案。接下来,读取多个文件:

Hadoop作业从多个目录获取输入文件

或将文件列表合并为单个数据帧:

使用Spark从目录中读取多个文件

问题解决了:

spark-submit ...
    --conf spark.hadoop.mapreduce.input.fileinputformat.input.dir.recursive=true 
    --conf spark.hive.mapred.supports.subdirectories=true 
    ...

在spark 2.1.0版本中必须这样设置参数:

.set("spark.hive.mapred.supports.subdirectories","true")
.set("spark.hadoop.mapreduce.input.fileinputformat.input.dir.recursive","true")

相关内容

最新更新