当使用mapPartitions时,binaryFiles何时加载到内存中?

时间:2017-01-20 16:15:33

标签: apache-spark pyspark azure-data-lake

我正在使用PySpark将训练有素的深度学习模型应用于图像,并关注内存使用量如何随着我当前的方法进行扩展。由于训练有素的模型需要一段时间才能加载,因此我会在每个工作人员上处理大批量的图像,代码类似于以下内容:

def run_eval(file_generator):
    trained_model = load_model()
    results = []
    for file in file_generator:
        # "file" is a tuple: [0] is its filename, [1] is the byte data
        results.append(trained_model.eval(file[1]))
    return(results)

my_rdd = sc.binaryFiles('adl://my_file_path/*.png').repartition(num_workers)
results = my_rdd.mapPartitions(run_eval)
results.collect()

如上所述,文件存储在关联的HDFS文件系统(特别是Azure Data Lake Store)中,可以通过SparkContext访问。

我的主要问题是:

  • 图像数据何时被加载到内存中?
    • 当发电机递增(“及时”)时,是否加载了每个图像的数据?
    • 在工作人员启动之前是否已加载整个分区的所有图像数据?
  • 负责从此关联文件系统加载数据的负责人(可能会产生瓶颈),或者工作人员是否从中加载了自己的数据?

同时感谢您就如何深入了解这些主题提出建议。

1 个答案:

答案 0 :(得分:2)

  

图像数据何时被加载到内存中?

     
      
  • 当发电机递增(“及时”)时,是否加载了每个图像的数据?
  •   

实际上,考虑到你的代码,它必须不止一次加载。首先它由JVM访问,然后转换为Python类型。在发生shuffle之后再次加载数据。每个过程都是懒惰的,因此加载不是问题。

所以你必须问自己的第一个问题是你是否真的需要洗牌。 binaryFiles具有minPartitions参数,可用于控制分区数。

另一个问题是非懒惰results list。使用生成器表达式会更有意义:

def run_eval(file_generator):
    trained_model = load_model()
    for file in file_generator:
        yield trained_model.eval(file[1])
  

头节点负责从这个关联的文件系统加载数据(可能会造成瓶颈),还是工作人员从中加载自己的数据?

不涉及中央处理。每个执行程序进程(Python)/线程(JVM)将加载其自己的数据集部分。