Kamuya açık bir Amazon s3 kaynağım (metin dosyası) var ve bu kaynağa erişmek istiyorum. Bunun anlamı - Hiç Amazon kimlik yok - Az önce indirmek istiyorsanız iyi çalışıyor:Erişilebilir erişim mevcuttur Amazon S3 dosyası: Apache Spark
val bucket = "<my-bucket>"
val key = "<my-key>"
val client = new AmazonS3Client
val o = client.getObject(bucket, key)
val content = o.getObjectContent // <= can be read and used as input stream
Ancak, kıvılcım bağlamda
val conf = new SparkConf().setAppName("app").setMaster("local")
val sc = new SparkContext(conf)
val f = sc.textFile(s"s3a://$bucket/$key")
println(f.count())
aynı kaynağı erişmeye çalıştığınızda aşağıdaki stacktrace hatayı alırsınız:
Exception in thread "main" com.amazonaws.AmazonClientException: Unable to load AWS credentials from any provider in the chain
at com.amazonaws.auth.AWSCredentialsProviderChain.getCredentials(AWSCredentialsProviderChain.java:117)
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3521)
at com.amazonaws.services.s3.AmazonS3Client.headBucket(AmazonS3Client.java:1031)
at com.amazonaws.services.s3.AmazonS3Client.doesBucketExist(AmazonS3Client.java:994)
at org.apache.hadoop.fs.s3a.S3AFileSystem.initialize(S3AFileSystem.java:297)
at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2653)
at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:92)
at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2687)
at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2669)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:371)
at org.apache.hadoop.fs.Path.getFileSystem(Path.java:295)
at org.apache.hadoop.mapred.FileInputFormat.listStatus(FileInputFormat.java:221)
at org.apache.hadoop.mapred.FileInputFormat.getSplits(FileInputFormat.java:270)
at org.apache.spark.rdd.HadoopRDD.getPartitions(HadoopRDD.scala:207)
at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:219)
at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:217)
at scala.Option.getOrElse(Option.scala:121)
at org.apache.spark.rdd.RDD.partitions(RDD.scala:217)
at org.apache.spark.rdd.MapPartitionsRDD.getPartitions(MapPartitionsRDD.scala:32)
at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:219)
at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:217)
at scala.Option.getOrElse(Option.scala:121)
at org.apache.spark.rdd.RDD.partitions(RDD.scala:217)
at org.apache.spark.SparkContext.runJob(SparkContext.scala:1781)
at org.apache.spark.rdd.RDD.count(RDD.scala:1099)
at com.example.Main$.main(Main.scala:14)
at com.example.Main.main(Main.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
herhangi AWS kimlik bilgilerini sağlamak istemiyoruz - sadece (şimdilik) anonim kaynağa erişmek istiyorum - nasıl bunu başarmak için? Muhtemelen AnonymousAWSCredentialsProvider gibi bir şey kullanmalıyım - ama bunu kıvılcım veya hadoop içine nasıl koyabilirim?
P.S. Benim durumum sadece durum
scalaVersion := "2.11.7"
libraryDependencies ++= Seq(
"org.apache.spark" %% "spark-core" % "1.4.1",
"org.apache.hadoop" % "hadoop-aws" % "2.7.1"
)
GÜNCELLEME: Bazı araştırmaları yaptıktan sonra - çalışmamasının nedenini gördüm. Her şeyden
Birincisi, S3AFileSystem kimlik bilgilerinin aşağıdaki sırayla ile AWS istemcisi oluşturur:
AWSCredentialsProviderChain credentials = new AWSCredentialsProviderChain(
new BasicAWSCredentialsProvider(accessKey, secretKey),
new InstanceProfileCredentialsProvider(),
new AnonymousAWSCredentialsProvider()
);
"accessKey" ve "SecretKey" değerlerini kıvılcım conf örneği alınır (tuşlar "fs.s3a olmalıdır. access.key "ve" fs.s3a.secret.key "veya org.apache.hadoop.fs.s3a.Constants.ACCESS_KEY ve org.apache.hadoop.fs.s3a.Constants.SECRET_KEY sabitleri, hangisi daha uygunsa).
İkincisi - muhtemelen AnonymousAWSCredentialsProvider'ın üçüncü seçenek (son öncelik) olduğunu görüyorsunuz - bunun nesi yanlış olabilir? Bu sadece erişim anahtarı ve gizli anahtar her ikisi için null döndürür
public class AnonymousAWSCredentials implements AWSCredentials {
public String getAWSAccessKeyId() {
return null;
}
public String getAWSSecretKey() {
return null;
}
}
: AnonymousAWSCredentials uygulanmasını bakın. Makul geliyor. Ama AWSCredentialsProviderChain içine bakmak: Hem tuşlar boş olduğu durumda sağlayıcı seçmez
AWSCredentials credentials = provider.getCredentials();
if (credentials.getAWSAccessKeyId() != null &&
credentials.getAWSSecretKey() != null) {
log.debug("Loading credentials from " + provider.toString());
lastUsedProvider = provider;
return credentials;
}
- anonim kimlik bilgileri çalışmaz anlamına gelir. Aws-java-sdk-1.7.4 içinde bir hataya benziyor. En son sürümü kullanmaya çalıştım - ama hadoop-aws-2.7.1 ile uyumsuz.
Başka bir fikrin var mı?
aracılığıyla sunulan AWS CLI
hayır, bunu bir süredir denemedim - bunu bile unuttum, hiçbir şey içinzon s3 kullanmayın – pkozlov