2016-03-04 126 views
1

我有一個Spark進程,它從S3獲取兩個輸入文件。在工作結束時,我只想用saveAsTextFile方法將結果寫回S3。但是,我得到Access Denied錯誤。spark saveAsTextFile到s3失敗

我的策略規則是敞開的,以確保我沒有任何權限錯誤:

{ 
    "Version": "2012-10-17", 
    "Id": "Policy1457106962648", 
    "Statement": [ 
     { 
      "Sid": "Stmt1457106959104", 
      "Effect": "Allow", 
      "Principal": "*", 
      "Action": "s3:*", 
      "Resource": "arn:aws:s3:::<bucket-name>/*" 
     } 
    ] 
} 

我設置SparkContext像下面的我的憑據:

SparkConf conf = new SparkConf() 
       .setAppName("GraphAnalyser") 
       .setMaster("local[*]") 
       .set("spark.driver.memory", "2G"); 
       .set("spark.hadoop.fs.s3.awsAccessKeyId", [access-key]) 
       .set("spark.hadoop.fs.s3n.awsAccessKeyId", [access-key]) 
       .set("spark.hadoop.fs.s3.awsSecretAccessKey", [secret-key]) 
       .set("spark.hadoop.fs.s3n.awsSecretAccessKey", [secret-key]); 

我使用通使用s3n協議的文件URL:

final String SC_NODES_FILE = "s3n://" + BUCKET_NAME + "/" + NODES_FILE; 
final String SC_EDGES_FILE = "s3n://" + BUCKET_NAME + "/" + EDGES_FILE; 
final String SC_OUTPUT_FILE = "s3n://" + BUCKET_NAME + "/output"; 

請注意,I訪問輸入文件沒有問題。看起來Spark對輸出文件發送HEAD請求,以確保它在嘗試保存最終結果之前不存在。由於s3返回Access Denied而不是Not Found。這可能是Spark拋出異常並退出的原因。

org.apache.hadoop.fs.s3.S3Exception: org.jets3t.service.S3ServiceException: S3 HEAD request failed for '/output.csv' - ResponseCode=403, ResponseMessage=Forbidden 

星火1.6.0 AWS-Java的SDK(58年1月10日) 火花core_2.10(1.6.0)

您的幫助表示讚賞。非常感謝你。

+0

嘗試檢查區域設置! AWS的API非常痛苦,不斷變化,錯誤信息不太具描述性。 – eliasah

回答

3

回答我的問題

事實證明,我所需要的s3:ListBucket動作,當資源是鬥本身,而不是鬥裏面的按鍵,只適用。

我在原來的政策文件,我有以下資源:

"Resource": "arn:aws:s3:::<bucket-name>/*" 

我不得不添加:

"Resource": "arn:aws:s3:::<bucket-name>/*" 

這是我的最終政策文件,該文件對我的作品:

{ 
    "Id": "Policy145712123124123", 
    "Version": "2012-10-17", 
    "Statement": [ 
    { 
     "Sid": "Stmt145712812312323", 
     "Action": [ 
     "s3:DeleteObject", 
     "s3:GetObject", 
     "s3:ListBucket", 
     "s3:PutObject" 
     ], 
     "Effect": "Allow", 
     "Resource": [ 
     "arn:aws:s3:::<bucket-name>", 
     "arn:aws:s3:::<bucket-name>/*" 
     ], 
     "Principal": { 
     "AWS": [ 
      "arn:aws:iam::<account-id>:user/<user-name>" 
     ] 
     } 
    } 
    ] 
}