我正在尝试将来自法兰克福(eu-central-1)的s3存储桶中的文件复制到我在爱尔兰通过EMR托管的hdfs(eu-west-1)。我尝试执行的复制命令:
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 V4export JAVA_OPTS="-Dcom.amazonaws.services.s3.enableV4 -Dcom.amazonaws.services.s3.enforceV4"
但无济于事。
这个事实让我尝试做以上所有,但在eu-central-1中使用了一个 NOT 的存储桶,例如在欧洲西部1号。那很有效。所以我想这就是它?
这个问题有解决方法吗?有人经历过这个吗?
修改
一种可行的替代方法是使用aws cli将数据从s3下载到主服务器上然后使用,例如
hdfs dfs -put <src> <dst>
完成工作。但是,如果真的大量数据不适合主节点该怎么办?
答案 0 :(得分:0)
我已设法通过指定端点将数据从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>/...
您不会也不应该在本地复制它。