vla*_*fol 5 python config pyspark
我想一次初始化配置,然后在我的PySpark项目的许多模块中使用它。
我看到两种方法。
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)
但是将一个外部参数传递给每个函数似乎并不美观。
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中处理从文件加载的常规配置的最佳实践是什么?
您的程序在 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 模块引用的每个文件夹中。