apache-spark - 问题 找不到 s3ablock-0001- 的任何有效本地目录

标签 apache-spark hadoop pyspark amazon-emr

当我尝试在 S3 上写入数据时,我在 Amazon EMR 上运行作业时遇到问题。

这是堆栈跟踪:

org.apache.hadoop.util.DiskChecker$DiskErrorException: Could not find any valid local directory for s3ablock-0001-
    at org.apache.hadoop.fs.LocalDirAllocator$AllocatorPerContext.getLocalPathForWrite(LocalDirAllocator.java:463)
    at org.apache.hadoop.fs.LocalDirAllocator$AllocatorPerContext.createTmpFileForWrite(LocalDirAllocator.java:477)
    at org.apache.hadoop.fs.LocalDirAllocator.createTmpFileForWrite(LocalDirAllocator.java:213)
    at org.apache.hadoop.fs.s3a.S3AFileSystem.createTmpFileForWrite(S3AFileSystem.java:589)
    at org.apache.hadoop.fs.s3a.S3ADataBlocks$DiskBlockFactory.create(S3ADataBlocks.java:811)
    at org.apache.hadoop.fs.s3a.S3ABlockOutputStream.createBlockIfNeeded(S3ABlockOutputStream.java:190)
    at org.apache.hadoop.fs.s3a.S3ABlockOutputStream.(S3ABlockOutputStream.java:168)
    at org.apache.hadoop.fs.s3a.S3AFileSystem.create(S3AFileSystem.java:822)
    at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:1125)
    at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:1105)
    at org.apache.parquet.hadoop.util.HadoopOutputFile.create(HadoopOutputFile.java:74)
    at org.apache.parquet.hadoop.ParquetFileWriter.(ParquetFileWriter.java:248)
    at org.apache.parquet.hadoop.ParquetOutputFormat.getRecordWriter(ParquetOutputFormat.java:390)
    at org.apache.parquet.hadoop.ParquetOutputFormat.getRecordWriter(ParquetOutputFormat.java:349)
    at org.apache.spark.sql.execution.datasources.parquet.ParquetOutputWriter.(ParquetOutputWriter.scala:37)
    at org.apache.spark.sql.execution.datasources.parquet.ParquetFileFormat$$anon$1.newInstance(ParquetFileFormat.scala:158)
    at org.apache.spark.sql.execution.datasources.SingleDirectoryDataWriter.newOutputWriter(FileFormatDataWriter.scala:126)
    at org.apache.spark.sql.execution.datasources.SingleDirectoryDataWriter.(FileFormatDataWriter.scala:111)
    at org.apache.spark.sql.execution.datasources.FileFormatWriter$.executeTask(FileFormatWriter.scala:264)
    at org.apache.spark.sql.execution.datasources.FileFormatWriter$.$anonfun$write$15(FileFormatWriter.scala:205)
    at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:90)
    at org.apache.spark.scheduler.Task.run(Task.scala:127)
    at org.apache.spark.executor.Executor$TaskRunner.$anonfun$run$3(Executor.scala:444)
    at org.apache.spark.util.Utils$.tryWithSafeFinally(Utils.scala:1377)
    at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:447)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

我使用 Apache Spark 3.0.1 和 Hadoop 3.2.1 使用 Amazon ECS for EMR 构建了一个镜像,我已经尝试使用 Apache Spark 2.4.5 和 Hadoop 2.7.1 但没有成功.

当我们在没有 ECS Image 的情况下手动构建 EMR 时,作业成功完成并将所需的一切写入 S3。

我恳求你们,我需要做些什么才能让这些东西运行起来?非常感谢。

最佳答案

你需要给app一个目录来存放数据

spark.hadoop.fs.s3a.buffer.dir /tmp,/drive1/tmp

通常它会选择 hadoop.tmp.dir 设置的内容。也许您只是没有足够的磁盘空间,或者该选项设置为小型根驱动器上的某个位置。

更好:为您拥有的每个磁盘都包含一个条目,它会尝试使用任何有足够空间的磁盘。

进一步阅读 How S3A writes data to S3

在 Hadoop 3.2.1 上,您可以告诉 S3A 在堆或字节缓冲区中进行缓冲,因此根本不使用本地磁盘。

spark.hadoop.fs.s3a.fast.upload.buffer bytebuffer

我们在一些进程对本地 FS 没有写入权限和/或没有容量的部署中这样做。但是您随后需要努力调整一些其他相关参数以避免缓冲过多数据 - 从 EC2 到 S3 的有限带宽会累积大量积压

实际上,这也可能是磁盘缓冲的问题 - 也许您只是创建数据的速度快于上传数据的速度。尝试限制单个输出流(此处为:spark 工作线程)在流写入 block 之前可以排队等待上传的 block 数:

spark.hadoop.fs.s3a.fast.upload.active.blocks 1

那个和/或更少数量的工作线程。

请更新这篇有用的帖子,以便其他人可以利用您的发现

关于apache-spark - 问题 找不到 s3ablock-0001- 的任何有效本地目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64342539/

相关文章:

python - 如何展平 pySpark 数据框?

mysql - 如何在配置单元中将时间戳转换为 gmt 格式

python - 返回 pyspark GroupedData 中具有最佳字段的行

hadoop - Oozie Workflow EL 函数 timestamp() 不给秒

hadoop - 启动后如何在沙箱上启动h2o

python - 绘制 Spark 数据框而不将其转换为 Pandas 的方法

apache-spark - Spark Master 填充临时目录

apache-spark - Apache Spark 中的非线性 (DAG) ML 管道

hadoop - 如何在 oozie 作业中指定多个 libpath?

dataframe - 如何用逗号分隔值拆分列并存储在 PySpark Dataframe 的数组中?如下所示