web-dev-qa-db-ja.com

Spark Streaming EC2クラスターアプリケーションでS3から入力を読み取る方法

私はSpark S3ディレクトリから彼の入力を読み込むストリーミングアプリケーションを作成しようとしていますが、spark-submitスクリプトで起動した後、この例外を取得し続けます:

Exception in thread "main" Java.lang.IllegalArgumentException: AWS Access Key ID and Secret Access Key must be specified as the username or password (respectively) of a s3n URL, or by setting the fs.s3n.awsAccessKeyId or fs.s3n.awsSecretAccessKey properties (respectively).
    at org.Apache.hadoop.fs.s3.S3Credentials.initialize(S3Credentials.Java:66)
    at org.Apache.hadoop.fs.s3native.Jets3tNativeFileSystemStore.initialize(Jets3tNativeFileSystemStore.Java:49)
    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:82)
    at org.Apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.Java:59)
    at org.Apache.hadoop.fs.s3native.$Proxy6.initialize(Unknown Source)
    at org.Apache.hadoop.fs.s3native.NativeS3FileSystem.initialize(NativeS3FileSystem.Java:216)
    at org.Apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.Java:1386)
    at org.Apache.hadoop.fs.FileSystem.access$200(FileSystem.Java:66)
    at org.Apache.hadoop.fs.FileSystem$Cache.get(FileSystem.Java:1404)
    at org.Apache.hadoop.fs.FileSystem.get(FileSystem.Java:254)
    at org.Apache.hadoop.fs.Path.getFileSystem(Path.Java:187)
    at org.Apache.spark.streaming.StreamingContext.checkpoint(StreamingContext.scala:195)
    at MainClass$.main(MainClass.scala:1190)
    at MainClass.main(MainClass.scala)
    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.spark.deploy.SparkSubmit$.launch(SparkSubmit.scala:292)
    at org.Apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:55)
    at org.Apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)

ここで提案されているように、このコードブロックを通じてこれらの変数を設定しています http://spark.Apache.org/docs/latest/ec2-scripts.html (ページの下部):

val ssc = new org.Apache.spark.streaming.StreamingContext(
  conf,
  Seconds(60))
ssc.sparkContext.hadoopConfiguration.set("fs.s3n.awsAccessKeyId",args(2))
ssc.sparkContext.hadoopConfiguration.set("fs.s3n.awsSecretAccessKey",args(3))

args(2)とargs(3)はもちろんAWSアクセスキーIDとSecreteアクセスキーです。

なぜ設定されていないのですか?

編集:私もこの方法で試しましたが、同じ例外が発生します:

val lines = ssc.textFileStream("s3n://"+ args(2) +":"+ args(3) + "@<mybucket>/path/")
26
gprivitera

奇数。 sparkContext.setも実行してみてください。アプリケーションを開始する前に、env変数もエクスポートしてみてください。

export AWS_ACCESS_KEY_ID=<your access>
export AWS_SECRET_ACCESS_KEY=<your secret>

^^これが私たちのやり方です。

更新:@tribbloidによると、1.3.0で上記の問題が発生したため、hdfs-site.xmlを使用して年齢や年齢をいじる必要があります。

val hadoopConf = sc.hadoopConfiguration;
hadoopConf.set("fs.s3.impl", "org.Apache.hadoop.fs.s3native.NativeS3FileSystem")
hadoopConf.set("fs.s3.awsAccessKeyId", myAccessKey)
hadoopConf.set("fs.s3.awsSecretAccessKey", mySecretKey)
24
samthebest

次の設定は私のために機能します。「fs.s3.impl」も設定してください。

val conf = new SparkConf().setAppName("Simple Application").setMaster("local")      
val sc = new SparkContext(conf)
val hadoopConf=sc.hadoopConfiguration;
hadoopConf.set("fs.s3.impl", "org.Apache.hadoop.fs.s3native.NativeS3FileSystem")
hadoopConf.set("fs.s3.awsAccessKeyId",myAccessKey)
hadoopConf.set("fs.s3.awsSecretAccessKey",mySecretKey)
22
harel

EMRを使用している場合は、= https://github.com/awslabs/emr-bootstrap-actions/tree/master/spark で説明されているようにSpark buildを使用しますs3:// URIを使用してS3を参照するだけで、資格情報はIAMまたはロールによって設定されるため、S3実装または追加の構成を設定する必要はありません。

3
ChristopherB

AWS EMRでは、上記の提案は機能しませんでした。代わりに、conf/core-site.xmlの次のプロパティを更新しました。

fs.s3n.awsAccessKeyIdおよびfs.s3n.awsSecretAccessKeyとS3資格情報。

3
Ishika Paul

最新のEMRリリース(4.6.0でテスト済み)には、次の構成が必要です。

val sc = new SparkContext(conf)
val hadoopConf = sc.hadoopConfiguration
hadoopConf.set("fs.s3.impl", "com.Amazon.ws.emr.hadoop.fs.EmrFileSystem")
hadoopConf.set("fs.s3.awsAccessKeyId", myAccessKey)
hadoopConf.set("fs.s3.awsSecretAccessKey", mySecretKey)

ほとんどの場合、すぐに使用できる設定が機能しますが、これは、クラスターを起動したものとは異なるS3資格情報を持っている場合です。

2
Dan Osipov

Javaでは、次のコード行があります。 SparkSessionではなく、SparkContextにのみAWS credsを追加する必要があります。

JavaSparkContext sc = new JavaSparkContext(spark.sparkContext());
sc.hadoopConfiguration().set("fs.s3a.access.key", AWS_KEY);
sc.hadoopConfiguration().set("fs.s3a.secret.key", AWS_SECRET_KEY);
0
Atihska

@nealmcbの答えを増やして、これを行う最も簡単な方法は定義することです

HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop 

conf/spark-env.shで、または~/.bashrcまたは~/.bash_profileでその環境変数をエクスポートします。

Hadoopを介してs3にアクセスできる限り、これは機能します。たとえば、実行できる場合

hadoop fs -ls s3n://path/

その後、hadoopはs3パスを確認できます。

Hadoopがパスを表示できない場合は、 ローカルのHadoop 2.6インストールからS3/S3nにアクセスするにはどうすればよいですか?

0
Bob Baxley

これは1.4.1シェルで機能します。

val conf = sc.getConf
conf.set("spark.hadoop.fs.s3.impl", "org.Apache.hadoop.fs.s3native.NativeS3FileSystem")
conf.set("spark.hadoop.fs.s3.awsAccessKeyId", <your access key>)
conf.set("spark.hadoop.fs.s3.awsSecretAccessKey", <your secret key>)
SparkHadoopUtil.get.conf.addResource(SparkHadoopUtil.get.newConfiguration(conf))
...
sqlContext.read.parquet("s3://...")
0
ru2nuts