根据本公告,亚马逊S3文件大小限制应为5T,但我在上传5G文件时出现以下错误
'/mahler%2Fparquet%2Fpageview%2Fall-2014-2000%2F_temporary%2F_attempt_201410112050_0009_r_000221_2222%2Fpart-r-222.parquet' XML Error Message:
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>EntityTooLarge</Code>
<Message>Your proposed upload exceeds the maximum allowed size</Message>
<ProposedSize>5374138340</ProposedSize>
...
<MaxSizeAllowed>5368709120</MaxSizeAllowed>
</Error>
这使得S3似乎只接受5G上传。我使用ApacheSparkSQL编写了一个使用SchemRDD.saveAsParquetFile
方法的Parquet数据集。完整堆栈跟踪是
org.apache.hadoop.fs.s3.S3Exception: org.jets3t.service.S3ServiceException: S3 PUT failed for '/mahler%2Fparquet%2Fpageview%2Fall-2014-2000%2F_temporary%2F_attempt_201410112050_0009_r_000221_2222%2Fpart-r-222.parquet' XML Error Message: <?xml version="1.0" encoding="UTF-8"?><Error><Code>EntityTooLarge</Code><Message>Your proposed upload exceeds the maximum allowed size</Message><ProposedSize>5374138340</ProposedSize><RequestId>20A38B479FFED879</RequestId><HostId>KxeGsPreQ0hO7mm7DTcGLiN7vi7nqT3Z6p2Nbx1aLULSEzp6X5Iu8Kj6qM7Whm56ciJ7uDEeNn4=</HostId><MaxSizeAllowed>5368709120</MaxSizeAllowed></Error>
org.apache.hadoop.fs.s3native.Jets3tNativeFileSystemStore.storeFile(Jets3tNativeFileSystemStore.java:82)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:82)
org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:59)
org.apache.hadoop.fs.s3native.$Proxy10.storeFile(Unknown Source)
org.apache.hadoop.fs.s3native.NativeS3FileSystem$NativeS3FsOutputStream.close(NativeS3FileSystem.java:174)
org.apache.hadoop.fs.FSDataOutputStream$PositionCache.close(FSDataOutputStream.java:61)
org.apache.hadoop.fs.FSDataOutputStream.close(FSDataOutputStream.java:86)
parquet.hadoop.ParquetFileWriter.end(ParquetFileWriter.java:321)
parquet.hadoop.InternalParquetRecordWriter.close(InternalParquetRecordWriter.java:111)
parquet.hadoop.ParquetRecordWriter.close(ParquetRecordWriter.java:73)
org.apache.spark.sql.parquet.InsertIntoParquetTable.org$apache$spark$sql$parquet$InsertIntoParquetTable$$writeShard$1(ParquetTableOperations.scala:305)
org.apache.spark.sql.parquet.InsertIntoParquetTable$$anonfun$saveAsHadoopFile$1.apply(ParquetTableOperations.scala:318)
org.apache.spark.sql.parquet.InsertIntoParquetTable$$anonfun$saveAsHadoopFile$1.apply(ParquetTableOperations.scala:318)
org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:62)
org.apache.spark.scheduler.Task.run(Task.scala:54)
org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:177)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
java.lang.Thread.run(Thread.java:745)
上传限制仍然是5T吗?如果是这样的话,我为什么会出现这个错误,我该如何修复它?
对象大小限制为5 TB。上传的大小仍然是5GB,如手册所述:
根据您上传的数据大小,Amazon S3提供以下选项:
在单个操作中上载对象--使用单个
PUT
操作,您可以上载大小最大为5GB的对象。分部分上传对象—使用多部分上传API,您可以上传大对象,最多可达5 TB。
http://docs.aws.amazon.com/AmazonS3/latest/dev/UploadingObjects.html
一旦你完成了多部分上传,S3就会验证并重新组合这些部分,然后你在S3中有一个大小高达5TB的单个对象,它可以作为一个实体下载,只需一个HTTPGET
请求。。。但上传速度可能要快得多,即使是在小于5GB的文件上,因为你可以并行上传部分,甚至可以重试第一次尝试时没有成功的部分的上传。
如果您使用aws-cli进行上传,您可以使用"aws-s3-cp"命令,这样它就不需要拆分和多部分上传
aws s3 cp masive-file.ova s3://<your-bucket>/<prefix>/masive-file.ova
诀窍似乎通常是弄清楚如何告诉S3进行多部分上传。对于将数据从HDFS复制到S3,这可以通过使用s3n文件系统来完成,特别是通过fs.s3n.multipart.uploads.enabled=true
实现多部分上传
可以这样做:
hdfs dfs -Dfs.s3n.awsAccessKeyId=ACCESS_KEY -Dfs.s3n.awsSecretAccessKey=SUPER_SECRET_KEY -Dfs.s3n.multipart.uploads.enabled=true -cp hdfs:///path/to/source/data s3n://bucket/folder/
可以在此处找到进一步的配置:https://hadoop.apache.org/docs/stable/hadoop-aws/tools/hadoop-aws/index.html