Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon ec2 如何在Spark Streaming EC2集群应用程序中从S3读取输入_Amazon Ec2_Amazon S3_Apache Spark - Fatal编程技术网

Amazon ec2 如何在Spark Streaming EC2集群应用程序中从S3读取输入

Amazon ec2 如何在Spark Streaming EC2集群应用程序中从S3读取输入,amazon-ec2,amazon-s3,apache-spark,Amazon Ec2,Amazon S3,Apache Spark,我试图让我的Spark Streaming应用程序从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, o

我试图让我的Spark Streaming应用程序从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)
我正在通过这段代码设置这些变量,如此处所示(页面底部):

args(2)和args(3)是我的AWS访问密钥ID,当然是秘密访问密钥

为什么它一直说它们没有设定

编辑:我也尝试过这种方法,但我得到了相同的异常:

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

奇数。还可以尝试在
sparkContext
上执行
.set
。在启动应用程序之前,请尝试导出环境变量:

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

以下配置适用于我,请确保还设置了“fs.s3.impl”:


在AWS EMR上,上述建议不起作用。相反,我更新了conf/core-site.xml中的以下属性:


带有S3凭据的fs.s3n.awsAccessKeyId和fs.s3n.awsSecretAccessKey

对于那些使用EMR的人,使用Spark构建,如中所述,只需使用S3://URI引用S3即可。无需设置S3实现或其他配置,因为凭据由IAM或角色设置

我想将凭据更安全地放在一个加密分区的配置文件中。因此,在运行spark应用程序之前,我确实导出了HADOOP_CONF_DIR=~/Private/.aws/HADOOP_CONF,并将一个名为
core site.xml
的文件(通过
ecryptfs
加密)放在该目录中,其中包含如下凭据:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
  <property>
  <name>fs.s3n.awsAccessKeyId</name>
  <value>my_aws_access_key_id_here</value>
  </property>
  <property>
  <name>fs.s3n.awsSecretAccessKey</name>
  <value>my_aws_secret_access_key_here</value>
  </property>
</configuration>

fs.s3n.awsAccessKeyId
我的密码在这里
fs.s3n.awsSecretAccessKey
我的密码在这里

HADOOP\u CONF\u DIR
也可以在
CONF/spark env.sh
中设置,这在1.4.1 shell中适用:

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://...")
val conf=sc.getConf
conf.set(“spark.hadoop.fs.s3.impl”、“org.apache.hadoop.fs.s3native.NativeS3FileSystem”)
conf.set(“spark.hadoop.fs.s3.awsAccessKeyId”,)
conf.set(“spark.hadoop.fs.s3.awsSecretAccessKey”,)
SparkHadoopUtil.get.conf.addResource(SparkHadoopUtil.get.newConfiguration(conf))
...
sqlContext.read.parquet(“s3:/…”)

补充@nealmcb的答案,最简单的方法是定义

HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop 
conf/spark env.sh
中,或在
~/.bashrc
~/.bash\u profile
中导出该env变量

只要您可以通过hadoop访问s3,这就行了。例如,如果您可以运行

hadoop fs -ls s3n://path/
然后hadoop可以看到s3路径

如果hadoop看不到路径,请遵循最新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凭据与java中启动集群时使用的凭据不同。

,下面是代码行。您只能在SparkContext中添加AWS凭据,而不能在SparkSession中添加

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);


你的意思是在使用spark submit之前从主程序和所有从程序中的shell导出它们?或者在执行应用程序之前,使用shell中的sys.env?在应用程序内部执行。仅在该shell中,不需要在除执行应用程序的shell之外的任何其他shell中执行它。在启动应用程序之前导出env变量是有效的!非常感谢。注意:在SparkConf()中设置
AWS\u ACCESS\u KEY\u ID
fs.s3n.awsAccessKeyId
。set(…)不起作用。在Env中设置AWS\u ACCESS\u KEY\u ID,或在spark Env.sh中设置它,确实有效。不幸的是,非工作案例应该可以工作。这在Spark 1.3之后不再有效。现在,如果您想静态设置它。您必须将hdfs-site.xml添加到Spark的conf目录中。无法在命令行中设置它。我不知道这个设计的意义,但它比将秘密转储到Env中要干净得多。在Python中,hadoopConfiguration属性似乎不可用。有什么解决方法吗?在pyspark中,它是
hadoopConf=sc.\u jsc.hadoopConfiguration()
@JosephLust cleaner根本不设置这些,而是使用IAM角色。你是在强迫某些东西在不需要的时候管理和保护这些秘密。@JaysonMinard说得对。我们在Spark集群上不使用EC2角色,因为作业是多租户的,其中特定的作业仅限于特定的存储桶。我们的分布式配置服务负责为适当的作业提供适当的机密。建议使用IAM角色而不是以任何其他方式指定密钥。根据当前的4.x EMR管理指南:我拥有用于创建spark cluster的IAM的所有S3权限。但我仍然面临着这个错误。@nishant这是EMR吗?如果是,EMR版本是什么?在EMR上,不要在Spark应用程序中设置AWS键。@Christopher我定义的角色有问题。我修复了它,现在它可以工作了。你为什么要逃避IAM角色?想改用访问/密钥吗?不是真的,我只是按照文档上的说明(当时)。现在,随着所有新的更新,对于大多数用例来说,这可能是一个过时的问题。您是否尝试过使用s3a://…访问文件?“上述”并不意味着任何问题,因为答案的顺序可以随时更改。对于EMR,@Christopher的答案看起来是正确的。这在技术上与@harel的答案相同,您只是从配置树的更高位置进行设置,而不是首先进入Hadoop配置。但是它是一样的,对于spark shell不一样-你已经在shell中有了sc和sqlContext,@harel的回答创建了一个新的conf和新的sc。
hadoop fs -ls s3n://path/
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)
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);