使用hadoop distcp将数据复制到s3块文件系统:指定的复制源大于复制源允许的最大大小

使用hadoop distcp将数据复制到s3块文件系统:指定的复制源大于复制源允许的最大大小,hadoop,amazon-s3,Hadoop,Amazon S3,我试图使用hadoop的distcp将数据从HDFS复制到S3(而不是S3N)。我的理解是,使用s3://协议,Hadoop将在s3上存储各个块,并且每个s3“文件”实际上都是一个HDFS块 Hadoop版本是在AmazonEMR上运行的2.2.0 但是,尝试执行一个简单的distcp,我得到以下错误: Caused by: Status Code: 400, AWS Service: Amazon S3, AWS Request ID: 71C64ECE79FCC244, AWS Error

我试图使用hadoop的
distcp
将数据从HDFS复制到S3(而不是S3N)。我的理解是,使用
s3://
协议,Hadoop将在s3上存储各个块,并且每个s3“文件”实际上都是一个HDFS块

Hadoop版本是在AmazonEMR上运行的2.2.0

但是,尝试执行一个简单的
distcp
,我得到以下错误:

Caused by: Status Code: 400, AWS Service: Amazon S3, AWS Request ID: 71C64ECE79FCC244, AWS Error Code: InvalidRequest, AWS Error Message: The specified copy source is larger than the maximum allowable size for a copy source: 5368709120, S3 Extended Request ID: uAnvxtrNolvs0qm6htIrKjpD0VFxzjqgIeN9RtGFmXflUHDcSqwnZGZgWt5PwoTy
    at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:619)
    at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:317)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:170)
    at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:2943)
    at com.amazonaws.services.s3.AmazonS3Client.copyObject(AmazonS3Client.java:1235)
    at org.apache.hadoop.fs.s3native.Jets3tNativeFileSystemStore.copy(Jets3tNativeFileSystemStore.java:277)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:186)
    at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:102)
    at org.apache.hadoop.fs.s3native.$Proxy11.copy(Unknown Source)
    at org.apache.hadoop.fs.s3native.NativeS3FileSystem.rename(NativeS3FileSystem.java:1217)
    at org.apache.hadoop.tools.mapred.RetriableFileCopyCommand.promoteTmpToTarget(RetriableFileCopyCommand.java:161)
    at org.apache.hadoop.tools.mapred.RetriableFileCopyCommand.doCopy(RetriableFileCopyCommand.java:110)
    at org.apache.hadoop.tools.mapred.RetriableFileCopyCommand.doExecute(RetriableFileCopyCommand.java:83)
    at org.apache.hadoop.tools.util.RetriableCommand.execute(RetriableCommand.java:87)
我的一些源文件大于5GB。看看这个错误,似乎distcp正试图盲目地将文件从HDFS复制到S3,就好像它使用的是S3本机文件系统一样。由于文件大于5GB,这是失败的,因为S3不支持大于5GB的put请求


为什么会这样?我原以为distcp会尝试将各个块放到S3上,而这些块的大小应该只有64MB(我的HDFS块大小)。

以下是wiki的示例:


为了写入大于4GB的文件,必须使用多部分上传。这似乎在Hadoop 2.4.0版中得到了修复(请参阅)


这就是为什么使用AWS原生Hadoop产品(如EMR和Qubole)是有意义的原因之一。他们已经准备好应对这种特质。(完全披露——我是@Qubole创始人之一)。除了普通的多部分上传外,我们还支持流式多部分上传,即即使在生成文件时,文件也会以小块的形式连续上传到S3。(在vanilla multipart upload中,我们首先等待文件完全生成,然后才分块上传到S3)。

Hadoop的文件系统界面不关心与它交互时的块级别(为什么应该?)。我想您需要手动拆分文件。那么如何使用
s3://
文件系统呢?如何将文件复制到其中?
% ${HADOOP_HOME}/bin/hadoop distcp hdfs://domU-12-31-33-00-02-DF:9001/user/nutch/0070206153839-1998 s3://123:456@nutch/