Amazon s3からJSONファイルを読み取ってsparkコンテキストを作成し、それを使用してデータを処理しようとしています。
Sparkは基本的にDockerコンテナーにあります。したがって、Dockerパスにファイルを配置することもPITAです。したがって、それをS3にプッシュしました。
以下のコードは残りの部分を説明しています。
from pyspark import SparkContext, SparkConf
conf = SparkConf().setAppName("first")
sc = SparkContext(conf=conf)
config_dict = {"fs.s3n.awsAccessKeyId":"**",
"fs.s3n.awsSecretAccessKey":"**"}
bucket = "nonamecpp"
prefix = "dataset.json"
filename = "s3n://{}/{}".format(bucket, prefix)
rdd = sc.hadoopFile(filename,
'org.Apache.hadoop.mapred.TextInputFormat',
'org.Apache.hadoop.io.Text',
'org.Apache.hadoop.io.LongWritable',
conf=config_dict)
次のエラーが表示されます-
Py4JJavaError Traceback (most recent call last)
<ipython-input-2-b94543fb0e8e> in <module>()
9 'org.Apache.hadoop.io.Text',
10 'org.Apache.hadoop.io.LongWritable',
---> 11 conf=config_dict)
12
/usr/local/spark/python/pyspark/context.pyc in hadoopFile(self, path, inputFormatClass, keyClass, valueClass, keyConverter, valueConverter, conf, batchSize)
558 jrdd = self._jvm.PythonRDD.hadoopFile(self._jsc, path, inputFormatClass, keyClass,
559 valueClass, keyConverter, valueConverter,
--> 560 jconf, batchSize)
561 return RDD(jrdd, self)
562
/usr/local/lib/python2.7/dist-packages/py4j/Java_gateway.pyc in __call__(self, *args)
536 answer = self.gateway_client.send_command(command)
537 return_value = get_return_value(answer, self.gateway_client,
--> 538 self.target_id, self.name)
539
540 for temp_arg in temp_args:
/usr/local/lib/python2.7/dist-packages/py4j/protocol.pyc in get_return_value(answer, gateway_client, target_id, name)
298 raise Py4JJavaError(
299 'An error occurred while calling {0}{1}{2}.\n'.
--> 300 format(target_id, '.', name), value)
301 else:
302 raise Py4JError(
Py4JJavaError: An error occurred while calling z:org.Apache.spark.api.python.PythonRDD.hadoopFile.
: 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:70)
at org.Apache.hadoop.fs.s3native.Jets3tNativeFileSystemStore.initialize(Jets3tNativeFileSystemStore.Java:73)
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:190)
at org.Apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.Java:103)
at org.Apache.hadoop.fs.s3native.$Proxy20.initialize(Unknown Source)
at org.Apache.hadoop.fs.s3native.NativeS3FileSystem.initialize(NativeS3FileSystem.Java:272)
at org.Apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.Java:2397)
at org.Apache.hadoop.fs.FileSystem.access$200(FileSystem.Java:89)
at org.Apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.Java:2431)
at org.Apache.hadoop.fs.FileSystem$Cache.get(FileSystem.Java:2413)
at org.Apache.hadoop.fs.FileSystem.get(FileSystem.Java:368)
at org.Apache.hadoop.fs.Path.getFileSystem(Path.Java:296)
at org.Apache.hadoop.mapred.FileInputFormat.singleThreadedListStatus(FileInputFormat.Java:256)
at org.Apache.hadoop.mapred.FileInputFormat.listStatus(FileInputFormat.Java:228)
at org.Apache.hadoop.mapred.FileInputFormat.getSplits(FileInputFormat.Java:304)
at org.Apache.spark.rdd.HadoopRDD.getPartitions(HadoopRDD.scala:201)
at org.Apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:205)
at org.Apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:203)
at scala.Option.getOrElse(Option.scala:120)
at org.Apache.spark.rdd.RDD.partitions(RDD.scala:203)
at org.Apache.spark.rdd.MappedRDD.getPartitions(MappedRDD.scala:28)
at org.Apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:205)
at org.Apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:203)
at scala.Option.getOrElse(Option.scala:120)
at org.Apache.spark.rdd.RDD.partitions(RDD.scala:203)
at org.Apache.spark.rdd.RDD.take(RDD.scala:1060)
at org.Apache.spark.rdd.RDD.first(RDD.scala:1093)
at org.Apache.spark.api.python.SerDeUtil$.pairRDDToPython(SerDeUtil.scala:202)
at org.Apache.spark.api.python.PythonRDD$.hadoopFile(PythonRDD.scala:543)
at org.Apache.spark.api.python.PythonRDD.hadoopFile(PythonRDD.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 py4j.reflection.MethodInvoker.invoke(MethodInvoker.Java:231)
at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.Java:379)
at py4j.Gateway.invoke(Gateway.Java:259)
at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.Java:133)
at py4j.commands.CallCommand.execute(CallCommand.Java:79)
at py4j.GatewayConnection.run(GatewayConnection.Java:207)
at Java.lang.Thread.run(Thread.Java:744)
AswSecretAccessKeyとawsAccessIdを明確に提供しました。どうしたの?
--packages org.Apache.hadoop:hadoop-aws:2.7.1
をspark-submitコマンドに追加することを解決しました。
S3でsparkジョブを実行できるようにする、すべてのhadoop不足パッケージをダウンロードします。
次に、ジョブで次のようにAWS認証情報を設定する必要があります。
sc._jsc.hadoopConfiguration().set("fs.s3n.awsAccessKeyId", aws_id)
sc._jsc.hadoopConfiguration().set("fs.s3n.awsSecretAccessKey", aws_key)
資格情報の設定に関するその他のオプションは、spark/conf/spark-envに資格情報を定義することです。
#!/usr/bin/env bash
AWS_ACCESS_KEY_ID='xxxx'
AWS_SECRET_ACCESS_KEY='xxxx'
SPARK_WORKER_CORES=1 # to set the number of cores to use on this machine
SPARK_WORKER_MEMORY=1g # to set how much total memory workers have to give executors (e.g. 1000m, 2g)
SPARK_EXECUTOR_INSTANCES=10 #, to set the number of worker processes per node
より詳しい情報:
私はこれを通過することをお勧めします link 。
私の場合、インスタンスプロファイルの認証情報を使用してs3データにアクセスしました。
インスタンスプロファイル認証情報-EC2インスタンスで使用され、Amazon EC2メタデータサービスを通じて配信されます。 JavaのAWS SDKは、InstanceProfileCredentialsProviderを使用してこれらの認証情報をロードします。
注意
インスタンスプロファイル認証情報は、AWS_CONTAINER_CREDENTIALS_RELATIVE_URIが設定されていない場合にのみ使用されます。詳細については、EC2ContainerCredentialsProviderWrapperを参照してください。
Pysparkの場合、設定を使用してs3コンテンツにアクセスします。
def get_spark_context(app_name):
# configure
conf = pyspark.SparkConf()
# init & return
sc = pyspark.SparkContext.getOrCreate(conf=conf)
# s3a config
sc._jsc.hadoopConfiguration().set('fs.s3a.endpoint',
's3.eu-central-1.amazonaws.com')
sc._jsc.hadoopConfiguration().set(
'fs.s3a.aws.credentials.provider',
'com.amazonaws.auth.InstanceProfileCredentialsProvider,'
'com.amazonaws.auth.profile.ProfileCredentialsProvider'
)
return pyspark.SQLContext(sparkContext=sc)
spark context here 。
タイプS3アクセスについては this を参照してください。