Spark Scala中如何处理环境变量 区分dev/prod路径配置
Spark 多环境路径配置无硬编码实现方案
以下是生产环境常用的三种落地方式,按推荐优先级排序:
方案1:Spark原生conf传参(最推荐,无额外依赖)
配置定义位置
不需要在代码仓库中存储任何环境相关的路径值,配置完全和代码解耦:
- dev环境:在本地IDEA运行配置、开发环境spark-submit提交脚本中定义路径参数
- prod环境:在生产调度系统(Airflow/Oozie等)的spark-submit提交脚本中定义路径参数
代码中访问方式
直接通过Spark内置的conf对象读取传入的参数即可,支持设置默认兜底值:
import org.apache.spark.sql.SparkSession val spark = SparkSession.builder() .appName("PathConfigDemo") .getOrCreate() // 读取传入的输入路径,未传参时默认取本地测试路径 val inputPath = spark.conf.get("my.biz.input.path", "file:///Users/xxx/test/data") val outputPath = spark.conf.get("my.biz.output.path", "file:///Users/xxx/test/output") // 业务逻辑 spark.read.parquet(inputPath).write.parquet(outputPath)
提交示例
dev环境提交时传入开发路径:
spark-submit \ --class com.yourpackage.BizJob \ --conf my.biz.input.path=hdfs://dev-cluster/path/to/data \ --conf my.biz.output.path=hdfs://dev-cluster/path/to/output \ your-job.jar
prod环境提交时只需要替换--conf后的路径为生产集群地址即可,代码不需要任何修改、重新打包。
方案2:Typesafe Config配置文件(适合配置项较多的场景)
如果你的作业除了路径还有几十上百个环境差异化参数,用配置文件管理更清晰。
配置定义位置
在项目src/main/resources目录下新建三类配置文件:
application.conf:存储所有环境通用的公共配置application-dev.conf:仅存储dev环境独有的配置(路径、并发度、调试开关等)application-prod.conf:仅存储prod环境独有的配置
以application-dev.conf为例,配置写法如下:
my.biz { input.path = "hdfs://dev-cluster/path/to/data" output.path = "hdfs://dev-cluster/path/to/output" source.partition = 20 }
application-prod.conf中对应替换路径、参数值为生产环境配置即可。
代码中访问方式
首先引入依赖(SBT依赖示例):
libraryDependencies += "com.typesafe" % "config" % "1.4.2"
代码中直接加载配置即可,不需要判断当前环境:
import com.typesafe.config.ConfigFactory // 自动加载启动时指定的环境配置文件 val conf = ConfigFactory.load() val inputPath = conf.getString("my.biz.input.path") val outputPath = conf.getString("my.biz.output.path") val partitionNum = conf.getInt("my.biz.source.partition")
启动作业时通过JVM参数指定当前加载哪个环境的配置文件:
- dev环境加启动参数
-Dconfig.resource=application-dev.conf - prod环境加启动参数
-Dconfig.resource=application-prod.conf
注意:集群模式提交时如果没有把配置打进Jar包,需要通过--files参数把对应环境的配置文件上传到集群类路径,否则会读取失败。
方案3:系统环境变量(适合容器化部署场景)
如果作业跑在K8s等容器化环境,用环境变量传参最方便。
配置定义位置
- dev环境:本地开发机环境变量、本地开发镜像ENV参数中定义
- prod环境:生产K8s配置、Yarn容器环境变量中定义
代码中访问方式
Scala原生支持读取系统环境变量,不需要额外依赖:
// 直接读取系统注入的环境变量 val inputPath = sys.env("BIZ_INPUT_PATH") val outputPath = sys.env("BIZ_OUTPUT_PATH")
避坑提醒:不要在代码中写
if (env == "dev") return "/dev/path" else return "/prod/path"这类分支逻辑,本质还是硬编码,后续新增测试、预发环境时必须改代码重新打包,维护成本极高。所有环境差异化配置都应该放在代码外部维护。
内容的提问来源于stack exchange,提问作者Ankit Gupta
相关产品推荐
相关产品推荐

