从外部文件加载配置的最佳PySpark做法是什么

vla*_*fol 5 python config pyspark

我想一次初始化配置,然后在我的PySpark项目的许多模块中使用它。

我看到两种方法。

  1. 在入口点加载它,并作为参数传递给每个函数

main.py:

with open(sys.argv[1]) as f:
    config = json.load(f)
df = load_df(config)
df = parse(df, config)
df = validate(df, config, strict=True)
dump(df, config)
Run Code Online (Sandbox Code Playgroud)

但是将一个外部参数传递给每个函数似乎并不美观。

  1. 在config.py中加载config并将该对象导入每个模块

config.py

import sys
import json
with open(sys.argv[1]) as f:
    config = json.load(f)
Run Code Online (Sandbox Code Playgroud)

main.py

from config import config
df = load_df()
df = parse(df)
df = validate(df, strict=True)
dump(df)
Run Code Online (Sandbox Code Playgroud)

并在每个模块中添加行

from config import config
Run Code Online (Sandbox Code Playgroud)

看起来更美,因为严格来讲config不是函数的参数。这是它们执行的一般上下文。

不幸的是,PySpark pickle config.py试图在服务器上执行它,但是没有将sys.argv传递给他们!所以,我在运行时看到错误

  File "/PycharmProjects/spark_test/config.py", line 6, in <module>
    CONFIG_PATH = sys.argv[1]
IndexError: list index out of range
Run Code Online (Sandbox Code Playgroud)

在PySpark中处理从文件加载的常规配置的最佳实践是什么?

gre*_*epe 4

您的程序在 master 上开始执行,并通过调用执行器上的一些函数将其主要工作传递给执行器。执行器是通常在不同物理机器上运行的不同进程。

因此,master 想要在执行器上引用的任何内容都需要是标准库函数(执行器可以访问)或可以发送的可挑选对象。

您通常不想在执行器上加载和解析任何外部资源,因为您总是必须复制它们并确保正确加载它们...传递一个可挑选的对象作为函数的参数(例如对于UDF) 的效果要好得多,因为代码中只有一处需要加载它。

我建议创建一个config.py文件并将其作为参数添加到您的spark-submit命令中:

spark-submit --py-files /path/to/config.py main_program.py
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样创建 Spark 上下文:

spark_context = SparkContext(pyFiles=['/path/to/config.py'])
Run Code Online (Sandbox Code Playgroud)

并且只需import config在您需要的地方使用即可。

您甚至可以将整个 python 包包含在打包为单个 zip 文件而不是单个config.py文件的树中,但请确保包含__init__.py在需要作为 python 模块引用的每个文件夹中。