尝试从 s3 读取镶木地板文件时出现一个非常奇怪的错误。我正在使用 spark book 中的以下代码片段。
package com.knx.rtb.sample
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.sql.SQLContext
import org.apache.spark.sql.functions._
// One method for defining the schema of an RDD is to make a case class with the desired column
// names and types.
case class Record(key: Int, value: String)
object SparkSql {
def main(args: Array[String]) {
val sparkConf = new SparkConf().setAppName("SparkSql")
val sc = new SparkContext(sparkConf)
sc.hadoopConfiguration.set("fs.s3n.awsAccessKeyId", "accesskey")
sc.hadoopConfiguration.set("fs.s3n.awsSecretAccessKey", "secretKey+JJbat7uEQtX/")
val sqlContext = new SQLContext(sc)
// Importing the SQL context gives access to all the SQL functions and implicit conversions.
import sqlContext.implicits._
val df = sc.parallelize((1 to 100).map(i => Record(i, s"val_$i"))).toDF()
//if I remove this line; then I got the error
df.write.parquet("s3n://adx-test/hdfs/pair.parquet")
// Read in parquet file. Parquet files are self-describing so the schmema is preserved.
val parquetFile = sqlContext.read.parquet("s3n://adx-test/hdfs/pair.parquet")
// Queries can be run using the DSL on parequet files just like the original RDD.
parquetFile.where($"key" === 1).select($"value".as("a")).collect().foreach(println)
// These files can also be registered as tables.
parquetFile.registerTempTable("parquetFile")
println("Result of Parquet file:")
sqlContext.sql("SELECT * FROM parquetFile").collect().foreach(println)
sc.stop()
}
}
代码片段运行没有任何问题。但是,每当我删除以下行时:df.write.parquet("s3n://adx-test/hdfs/pair.parquet")
这意味着将 parquet 文件从 s3 读取到 spark 数据帧中(不先写入 parquet 文件),我收到一个错误:
线程“main”java.lang.IllegalArgumentException 中的异常:AWS 访问密钥 ID 和秘密访问密钥必须分别指定为 s3n URL 的用户名或密码,或者通过设置 fs.s3n.awsAccessKeyId 或 fs.s3n。 awsSecretAccessKey 属性(分别)。
这很奇怪,因为我已经在代码片段的顶部设置了 hadoopConfiguration s3AccessKeyId 和 secret。我想尝试使用带格式的 s3n url,s3n://accessId:secret@bucket/path
但似乎当 secret 包含/
字符时;它行不通。