【问题标题】:Signature error while connecting to s3 bucket via sparklyr通过 sparklyr 连接到 s3 存储桶时出现签名错误
【发布时间】:2018-05-13 06:25:25
【问题描述】:

当我尝试使用 sparklyr 从 R studio 连接到 s3 存储桶时遇到错误。 s3 存储桶位于 eu-central-1(Frankfurt) 区域。 Spark 版本 - 2.1.0,Hadoop 2.7。我收到带有签名不匹配错误的 403 响应代码。但是,当我尝试获取 s3a 存储桶时,却得到 400 响应代码。任何关于通过 R studio 中的 spark 连接到 s3 存储桶的替代方法的消息,也值得赞赏。在没有 Spark 的情况下,与 s3 的连接也能正常工作。

这里是代码,

   # install.packages("devtools")
# devtools::install_github("rstudio/sparklyr") 
library(sparklyr)
library(dplyr)
sc <- spark_connect(master = "local")
spark_disconnect(sc)
config <- spark_config()
library(sparklyr)
library(dplyr)
# config$sparklyr.defaultPackages <- "org.apache.hadoop:hadoop-aws:2.7.3"
# config$spark.executor.memory <- "4g"
sc <- spark_connect(master = "local",config = config)


ctx <- sparklyr::spark_context(sc)
jsc <- invoke_static(
sc,
"org.apache.spark.api.java.JavaSparkContext",
"fromSparkContext",
ctx
)


hconf <- jsc %>% invoke("hadoopConfiguration")
hconf %>% invoke("set","fs.s3.access.key", "xx")
hconf %>% invoke("set","fs.s3.secret.key", "xx")
#hconf %>% invoke("set","com.amazonaws.services.s3.enableV4", "true")
test <- spark_read_csv(sc, "test", "s3://********.csv")
Error: org.apache.hadoop.fs.s3.S3Exception: org.jets3t.service.S3ServiceException: Service Error Message. -- ResponseCode: 403, ResponseStatus: Forbidden, XML Error Message: <?xml version="1.0" encoding="UTF-8"?><Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><AWSAccessKeyId>AKIAJ3ZD2ZEISKNQMSGQ</AWSAccessKeyId><StringToSign>AWS4-HMAC-SHA25620171129T123633Z20171129/eu-central-1/s3/aws4_request555016eca303c98732f51adcaaa83eac7368fb75f59eaa9f59116684b9030ee0</StringToSign><SignatureProvided>bf703f56827aa0f04aab3fa6a1e2aa277117344cdbfc3f4f3e51895ce62af826</SignatureProvided><StringToSignBytes>41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 0a 32 30 31 37 31 31 32 39 54 31 32 33 36 33 33 5a 0a 32 30 31 37 31 31 32 39 2f 65 75 2d 63 65 6e 74 72 61 6c 2d 31 2f 73 33 2f 61 77 73 34 5f 72 65 71 75 65 73 74 0a 35 35 35 30 31 36 65 63 61 33 30 33 63 39 38 37 33 32 66 35 31... <truncated>
    at org.apache.hadoop.fs.s3.Jets3tFileSystemStore.get(Jets3tFileSystemStore.java:175)
    at org.apache.hadoop.fs.s3.Jets3tFileSystemStore.retrieveINode(Jets3tFileSystemStore.java:221)
    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:498)
    at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:191)
    at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:102)
    at com.sun.proxy.$Proxy23.retrieveINode(Unknown Source)
    at org.apache.hadoop.fs.s3.S3FileSystem.getFileStatus(S3FileSystem.java:340)
    at org.apache.hadoop.fs.FileSystem.exists(FileSystem.java:1426)
    at org.apache.spark.sql.execution.datasources.DataSource$$anonfun$14.apply(DataSource.scala:381)
    at org.apache.spark.sql.execution.datasources.DataSource$$anonfun$14.apply(DataSource.scala:370)
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:241)
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:241)
    at scala.collection.immutable.List.foreach(List.scala:381)
    at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:241)
    at scala.collection.immutable.List.flatMap(List.scala:344)
    at org.apache.spark.sql.execution.datasources.DataSource.resolveRelation(DataSource.scala:370)
    at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:152)
    at org.apache.spark.sql.DataFrameReader.csv(DataFrameReader.scala:415)
    at org.apache.spark.sql.DataFrameReader.csv(DataFrameReader.scala:352)
    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:498)
    at sparklyr.Invoke$.invoke(invoke.scala:102)
    at sparklyr.StreamHandler$.handleMethodCall(stream.scala:97)
    at sparklyr.StreamHandler$.read(stream.scala:62)
    at sparklyr.BackendHandler.channelRead0(handler.scala:52)
    at sparklyr.BackendHandler.channelRead0(handler.scala:14)
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:367)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:353)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:346)
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:367)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:353)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:346)
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:267)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:367)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:353)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:346)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1294)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:367)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:353)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:911)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:652)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:575)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:489)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:451)
    at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:140)
    at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.jets3t.service.S3ServiceException: Service Error Message. -- ResponseCode: 403, ResponseStatus: Forbidden, XML Error Message: <?xml version="1.0" encoding="UTF-8"?><Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><AWSAccessKeyId>AKIAJ3ZD2ZEISKNQMSGQ</AWSAccessKeyId><StringToSign>AWS4-HMAC-SHA25620171129T123633Z20171129/eu-central-1/s3/aws4_request555016eca303

【问题讨论】:

    标签: r amazon-web-services hadoop amazon-s3 sparklyr


    【解决方案1】:

    这可能是由于区域之间的签名版本不兼容。有些地区不支持签名版本 2,您必须使用此处提到的版本 4 - http://docs.aws.amazon.com/general/latest/gr/signature-version-2.html#signature-2-regions-services

    当涉及到 S3 存储桶/对象访问时,您必须在请求中指定区域名称 (eu-central-1)。

    【讨论】:

    • hconf %>% invoke("set","com.amazonaws.services.s3.enableV4", "true") 应该强制执行 v4 签名,对吗?不幸的是,这似乎并没有解决问题。
    • @Krishnan 您是否指定了 --region 开关?另外,看看这个包是否可以帮助你 - github.com/cloudyr/aws.s3 ?
    • Hadoop 与 S3 交互也存在一些协议问题,详情请查看此页面 - hadoop.apache.org/docs/current/hadoop-aws/tools/hadoop-aws/…
    • 感谢您的回信,aws.s3 连接工作正常,但难以加载非常大的数据文件。签名问题仅与火花有关。谢谢你的链接,看看。
    【解决方案2】:

    您需要通过以下方式设置您的 AWS 凭证

    Sys.setenv(AWS_ACCESS_KEY_ID="[Your access key]")
    Sys.setenv(AWS_SECRET_ACCESS_KEY="[Your secret access key]")
    

    ?spark_read_csv

    config$sparklyr.defaultPackages <- "org.apache.hadoop:hadoop-aws:2.7.3" 也是必不可少的。

    【讨论】:

    • 是的,我已经尝试通过 Sys.setenv() 设置凭据,也在 hconf %>% invoke("set","fs.s3.access.key", "xx" ) 以及 spark-defaults.conf 文件中,当我运行 SparkUI URL 时,我可以看到环境中的值。
    • 您是否尝试过使用 Scala 通过 spark-shell 访问存储桶?可能不是更具体的问题
    • 感谢您的回信。 scala&gt; sc.hadoopConfiguration.set("fs.s3n.impl", "org.apache.hadoop.fs.s3native.NativeS3FileSystem") scala&gt; sc.hadoopConfiguration.set("fs.s3.access.key", "**") scala&gt; sc.hadoopConfiguration.set("fs.s3.secret.key", "**") sc.hadoopConfiguration.set("fs.s3.endpoint","s3.eu-central-1.amazonaws.com") val file = spark.sqlContext.load("s3://****.csv") ResponseStatus:Forbidden, XML Error Message: &lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;Error&gt;&lt;Code&gt;InvalidAccessKeyId&lt;/Code&gt;&lt;Message&gt;The AWS Access Key Id you provided does not exist in our records.&lt;/Message&gt;
    【解决方案3】:

    如果您使用的是亚马逊自己的 EMR,那么您需要查看他们的文档。

    如果您使用的是 Apache 自己的工件,那么您需要关闭 s3 到 s3a 文件系统连接器,然后启用

    1. 将JVM系统属性com.amazonaws.services.s3.enableV4设置为true
    2. 将端点fs.s3a.endpoint 设置为您要与之交谈的特定商店的端点see the list

    如果事情不正常,您会收到一条相当笼统的“400 bad request”消息,这对于找出问题的原因没有多大用处。首先让事情与 s3 美国东部 (s3a://landsat-pds) 中的存储桶一起工作,然后尝试列出,然后移至 v4 区域中的存储桶。

    【讨论】:

      猜你喜欢
      • 2017-12-24
      • 1970-01-01
      • 2014-02-05
      • 2021-09-09
      • 1970-01-01
      • 2015-10-28
      • 2018-06-19
      • 2020-05-15
      • 2016-07-23
      相关资源
      最近更新 更多