我正在尝试将文件从法兰克福的一个s3存储桶(eu-central-1)复制到通过爱尔兰的EMR(eu-west-1)托管的hdfs中。我尝试在以下位置执行复制命令:
hdfs dfs -cp "s3a://<bucket>/<file>" /user/hadoop/<file>
和
s3-dist-cp --src "s3a://<bucket>/" --dest hdfs:///user/hadoop/ --srcPattern <file>
和
hadoop distcp "s3a://<bucket>/<file>" /user/hadoop/<file>
在所有情况下(以及所有这些命令上有关附加选项和s3,s3a,s3n的各种排列),我确实得到类似以下异常的信息:
16/01/15 11:48:24 ERROR tools.DistCp: Exception encountered
com.amazonaws.services.s3.model.AmazonS3Exception: Bad Request (Service: Amazon S3; Status Code: 400; Error Code: 400 Bad Request; Request ID: 4A77158C1BD71C29), S3 Extended Request ID: LU41MspxqVnHqyaMreTvggRG480Wb9d+TBx1MAo5v/g9yz07mmPizcZVOtRMQ+GElXs8vl/WZXA=
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:1219)
at com.amazonaws.http.AmazonHttpClient.executeOneRequest(AmazonHttpClient.java:803)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:505)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:317)
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3595)
at com.amazonaws.services.s3.AmazonS3Client.headBucket(AmazonS3Client.java:1041)
at com.amazonaws.services.s3.AmazonS3Client.doesBucketExist(AmazonS3Client.java:1013)
at org.apache.hadoop.fs.s3a.S3AFileSystem.initialize(S3AFileSystem.java:154)
at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2644)
at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:90)
at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2678)
at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2660)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:374)
at org.apache.hadoop.fs.Path.getFileSystem(Path.java:296)
at org.apache.hadoop.tools.GlobbedCopyListing.doBuildListing(GlobbedCopyListing.java:76)
at org.apache.hadoop.tools.CopyListing.buildListing(CopyListing.java:84)
at org.apache.hadoop.tools.DistCp.createInputFileListing(DistCp.java:353)
at org.apache.hadoop.tools.DistCp.execute(DistCp.java:160)
at org.apache.hadoop.tools.DistCp.run(DistCp.java:121)
at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)
at org.apache.hadoop.tools.DistCp.main(DistCp.java:401)
所以我想使用s3a在后台使用亚马逊的sdk。经过大量研究,我找到了推测的原因:
链接:Amazon s3a returns 400 Bad Request with Spark
链接:https://github.com/aws/aws-sdk-java/issues/360
因此,总的来说,法兰克福和其他一些较新的中心“只能”使用签名版本4,但是hadoop cp,distcp或s3-dist-cp可以使用的所有命令都是使用版本2?
由于使用s3a正在使用aws sdk,因此我尝试通过添加来强制使用Signature V4
export JAVA_OPTS="-Dcom.amazonaws.services.s3.enableV4 -Dcom.amazonaws.services.s3.enforceV4"
但无济于事。
这个事实使我尝试了上述所有操作,但在eu-central-1中使用了桶 NOT ,但例如在eu-west-1上。那行得通。所以我想是吗?
有解决这个问题的方法吗?有人也经历过吗?
编辑
一种可行的替代方法是使用aws cli将s3中的数据下载到主服务器上,然后使用例如
hdfs dfs -put <src> <dst>
完成工作。但是,如果这真的是海量数据不适合主节点,该怎么办?
最佳答案
我已经通过指定端点从s3,FRA到HDFS的数据获取:
hdfs dfs -Dfs.s3a.awsAccessKeyId=<access key ID> -Dfs.s3a.awsSecretAccessKey=<secret acces key> -Dfs.s3a.endpoint=<s3 enpoint> -ls s3a://<bucket_name>/...
您不应该也不应该在本地复制它。
关于hadoop - AmazonS3Exception错误的请求:从法兰克福S3到EMR HDFS的distcp失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34810759/