从外部文件

时间:2017-09-25 13:13:57

标签: python pyspark config

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

我看到了两种方法。

  1. 将其加载到入口点并作为参数传递给每个函数
  2. 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)
    

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

    1. 在config.py中加载配置并在每个模块中导入此对象
    2. config.py

      import sys
      import json
      with open(sys.argv[1]) as f:
          config = json.load(f)
      

      main.py

      from config import config
      df = load_df()
      df = parse(df)
      df = validate(df, strict=True)
      dump(df)
      

      并在每个模块中添加行

      from config import 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
      

      在PySpark中使用从文件加载的常规配置的最佳做法是什么?

1 个答案:

答案 0 :(得分:2)

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

因此,主人想要在执行者身上引用的任何东西都需要是标准库函数(执行者可以访问的)或者可以发送的可伪装对象。

您通常不想加载和解析执行程序上的任何外部资源,因为您始终必须将它们复制并确保正确加载它们...将可伪装对象作为参数传递函数(例如对于UDF)工作得更好,因为代码中只有一个位置需要加载它。

我建议创建一个int *array = malloc(length*sizeof(*array));文件并将其作为参数添加到config.py命令中:

spark-submit

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

spark-submit --py-files /path/to/config.py main_program.py

只需在您需要的地方使用spark_context = SparkContext(pyFiles=['/path/to/config.py'])

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