【问题标题】:How to use TypeSafe config with Apache Spark?如何在 Apache Spark 中使用 TypeSafe 配置?
【发布时间】:2020-11-16 09:44:00
【问题描述】:

我有一个 Spark 应用程序,我正在尝试将其打包为 fat jar 并使用 spark-submit 部署到本地集群。我正在使用 Typesafe config 为各种部署环境创建配置文件 - local.confstaging.confproduction.conf - 并尝试提交我的 jar。

我正在运行的命令如下:

/opt/spark-3.0.1-bin-hadoop2.7/bin/spark-submit \
--master spark://127.0.0.1:7077 \
--files ../files/local.conf \
--driver-java-options '-Dconfig.file=local.conf' \
target/scala-2.12/spark-starter-2.jar  

我通过一个接一个地添加选项来逐步构建命令。使用--files,日志显示文件正在上传到 Spark,但是当我添加 --driver-java-options 时,提交失败,找不到文件。

Caused by: java.io.FileNotFoundException: local.conf (No such file or directory)
        at java.base/java.io.FileInputStream.open0(Native Method)
        at java.base/java.io.FileInputStream.open(FileInputStream.java:219)
        at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
        at com.typesafe.config.impl.Parseable$ParseableFile.reader(Parseable.java:629)
        at com.typesafe.config.impl.Parseable.reader(Parseable.java:99)
        at com.typesafe.config.impl.Parseable.rawParseValue(Parseable.java:233)
        at com.typesafe.config.impl.Parseable.parseValue(Parseable.java:180)
        ... 35 more

代码:

import com.example.spark.settings.Settings
import com.typesafe.config.ConfigFactory
import org.apache.spark.sql.SparkSession

object App extends App {
  val config = ConfigFactory.load()
  val settings = Settings(config = config)

  val spark = SparkSession
    .builder()
    .getOrCreate()

  spark.stop()
}

我需要更改哪些内容才能单独提供配置文件?

【问题讨论】:

  • @Srinivas 用代码更新了问题。它并没有故意做太多,因为我正在测试配置。 :)

标签: scala apache-spark typesafe-config


【解决方案1】:

根据Spark Docs--files被放置在每个执行器的工作目录下。当您尝试从驱动程序而不是执行程序访问此文件时。

为了在驱动端加载配置,试试这样的:

/opt/spark-3.0.1-bin-hadoop2.7/bin/spark-submit \
--master spark://127.0.0.1:7077 \
--driver-java-options '-Dconfig.file=../files/local.conf' \
target/scala-2.12/spark-starter-2.jar  

如果你想要在执行器端加载配置,你需要使用spark.executor.extraJavaOptions 属性。在这种情况下,您需要在执行器上运行的 lambda 中加载配置,例如 RDD API:


myRdd.map { row => 
  val config = ConfigFactory.load()
  ...
}

config 的可见性将被限制在 lambda 的范围内。这是一种相当复杂的方式,我将在下面描述一个更好的选择。

我对如何在 Spark 中使用自定义配置的一般建议:

  1. 阅读this chapter of Spark Docs
  2. 在驱动端加载配置
  3. 将您需要的设置映射到不可变案例类
  4. 通过闭包将此案例类传递给执行者
  5. 请记住,带有设置的案例类应包含尽可能少的数据,任何字段类型都应为原始类型或实现java.io.Serializable

EMR 的特点是很难访问驱动程序的文件系统。因此,最好将配置存储在外部存储中,通常是 S3。

Typesafe 配置库无法直接从 S3 加载文件,因此您可以将配置的路径作为 app 参数而不是 -Dproperty 传递,使用 AmazonS3Client 从 S3 读取它,然后使用ConfigFactory.parseString()。以this answer 为例。

【讨论】:

  • 如果我可以添加一个后续问题,同样的spark-submit 策略是否适用于例如 Amazon EMR(我们计划在其中运行代码)或者我是否需要任何特定于 Amazon 的配置管理的变化?
  • 在答案中添加了特定于 EMR 的建议。简而言之,它会影响您在驱动程序端加载配置的方式,但不会影响您将其传递给执行程序的方式(案例类 + 闭包)。
猜你喜欢
  • 2016-12-16
  • 1970-01-01
  • 1970-01-01
  • 2016-06-23
  • 2013-07-28
  • 2014-08-03
  • 2018-05-24
  • 2016-06-08
  • 2014-01-02
相关资源
最近更新 更多