如何在 Apache Spark 中使用 TypeSafe 配置?
How to use TypeSafe config with Apache Spark?
我有一个 Spark 应用程序,我试图将其打包为一个胖 jar 并使用 spark-submit
部署到本地集群。我正在使用 Typesafe 配置为各种部署环境创建配置文件 - local.conf
、staging.conf
和 production.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()
}
我需要更改什么才能单独提供配置文件?
根据Spark Docs,--files
放在每个executor的工作目录下。当您尝试从驱动程序而不是执行程序访问此文件时。
为了在驱动端加载配置,尝试这样的事情:
/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 中使用自定义配置的一般建议:
- 阅读this chapter of Spark Docs
- 在驱动端加载配置
- 将您需要的设置映射到不可变大小写 class
- 通过闭包将这个案例class传递给执行者
- 请记住,带设置的案例 class 应该包含尽可能少的数据,任何字段类型都应该是原始的或实现的
java.io.Serializable
EMR 具体是很难访问驱动程序的文件系统。所以最好将配置存储在外部存储中,通常是 S3。
类型安全配置库无法直接从 S3 加载文件,因此您可以将路径作为应用参数传递给配置,而不是 -D属性,使用 [=16] 从 S3 读取它=] 然后使用 ConfigFactory.parseString()
将其加载为配置。以 this answer 为例。
我有一个 Spark 应用程序,我试图将其打包为一个胖 jar 并使用 spark-submit
部署到本地集群。我正在使用 Typesafe 配置为各种部署环境创建配置文件 - local.conf
、staging.conf
和 production.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()
}
我需要更改什么才能单独提供配置文件?
根据Spark Docs,--files
放在每个executor的工作目录下。当您尝试从驱动程序而不是执行程序访问此文件时。
为了在驱动端加载配置,尝试这样的事情:
/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 中使用自定义配置的一般建议:
- 阅读this chapter of Spark Docs
- 在驱动端加载配置
- 将您需要的设置映射到不可变大小写 class
- 通过闭包将这个案例class传递给执行者
- 请记住,带设置的案例 class 应该包含尽可能少的数据,任何字段类型都应该是原始的或实现的
java.io.Serializable
EMR 具体是很难访问驱动程序的文件系统。所以最好将配置存储在外部存储中,通常是 S3。
类型安全配置库无法直接从 S3 加载文件,因此您可以将路径作为应用参数传递给配置,而不是 -D属性,使用 [=16] 从 S3 读取它=] 然后使用 ConfigFactory.parseString()
将其加载为配置。以 this answer 为例。