Spark SQL 2.0.0 坑 小记

问题出现

这个异常已在 Spakr SQL 2.0.1 中修复

使用 IDEA 配置好 Spark SQL 2.0.0 开始使用

 // 构建会话
 val ss: SparkSession =SparkSession.builder
                                    .master("local")
                                    .appName("Word Count")
                                    .getOrCreate()
// 读取文件
val jsonData: DataFrame = ss.read.json("indata/data.json")

运行会产生一个路径异常,这个路径SparkSQL 内置的 Hive 创表保存数据默认路径的。

java.net.URISyntaxException: Relative path in absolute URI: file:E:/IdeaProject/SparkDemo/spark-warehouse

问题解决

// 构建 Spark SQL 会话
        val ss: SparkSession = SparkSession.builder
            .master("local")
            .appName("Word Count")
            .config("spark.sql.warehouse.dir", "项目根路径")
            .getOrCreate()

问题解析

查看源码发现,这个问题出在 SQLConf.scala 里面

  • 源码目录:org.apache.spark.sql.internal.SQLConf

提取相关源码

// 默认配置模板
val WAREHOUSE_PATH = SQLConfigBuilder("spark.sql.warehouse.dir")
    .doc("The default location for managed databases and tables.")
    .stringConf
    .createWithDefault("file:${system:user.dir}/spark-warehouse")

// 替换 模板里的路径,问题就出现这个替换的上
def warehousePath: String = {
    getConf(WAREHOUSE_PATH).replace("${system:user.dir}", System.getProperty("user.dir"))
  }

我们可以把这段逻辑简化一下

使用这段代码 System.getProperty("user.dir") 替换路径,输出结果发现 其中的含有 \,这就是异常的原因

val path = "file:${system:user.dir}/spark-warehouse".replace("${system:user.dir}", System.getProperty("user.dir"))
println(path)
--------------
file:E:\IdeaProject\SparkDemo/spark-warehouse

官方修复动态

管方已在 Spark SQL 2.0.1 版本中修复这个BUG

修复代码如下

val WAREHOUSE_PATH = SQLConfigBuilder("spark.sql.warehouse.dir")
    .doc("The default location for managed databases and tables.")
    .stringConf
    .createWithDefault("${system:user.dir}/spark-warehouse")

def warehousePath: String = {
    new Path(getConf(WAREHOUSE_PATH).replace("${system:user.dir}",
      System.getProperty("user.dir"))).toString
  }
发表评论 / Comment

用心评论~