数据从Spark中的RDD以什么顺序进行处理?

时间:2016-03-23 22:05:43

标签: python multithreading apache-spark parallel-processing pyspark

上下文
Spark提供了RDD,可以使用map函数来懒惰地设置并行处理的操作。可以使用指定的分区参数创建RDD,该参数确定每个RDD要创建的分区数,最好是此参数等于系统数(例如,您要处理12个文件,创建一个包含3个分区的RDD,分割4个系统的数据分别为4个桶,所有文件在每个系统中同时处理)。据我所知,这些分区控制着每个系统进行处理的数据部分。

问题
我需要微调并控制每个系统同时运行多少个函数。如果两个或多个函数同时在同一个GPU上运行,系统将崩溃。

问题
如果RDD不能很好地分割(如上例所示),那么在系统上并发运行多少个线程?

示例
在:

sample_files = ['one.jpg','free.jpg','two.png','zero.png',
                'four.jpg','six.png','seven.png','eight.jpg',
                'nine.png','eleven.png','ten.png','ten.png',
                'one.jpg','free.jpg','two.png','zero.png',
                'four.jpg','six.png','seven.png','eight.jpg',
                'nine.png','eleven.png','ten.png','ten.png',
                'eleven.png','ten.png']
CLUSTER_SIZE = 3
example_rdd = sc.parallelize(sample_files, CLUSTER_SIZE)
example_partitions = example_rdd.glom().collect()

# Print elements per partition
for i, l in enumerate(example_partitions): print "parition #{} length: {}".format(i, len(l))
# Print partition distribution
print example_partitions

# How many map functions run concurrently when the action is called on this Transformation?
example_rdd.map(lambda s: (s, len(s))
action_results = example_rdd.reduceByKey(add)

输出:

parition #0 length: 8
parition #1 length: 8
parition #2 length: 10
[ ['one.jpg', 'free.jpg', 'two.png', 'zero.png', 'four.jpg', 'six.png', 'seven.png', 'eight.jpg'], 
['nine.png', 'eleven.png', 'ten.png', 'ten.png', 'one.jpg', 'free.jpg', 'two.png', 'zero.png'], 
['four.jpg', 'six.png', 'seven.png', 'eight.jpg', 'nine.png', 'eleven.png', 'ten.png', 'ten.png', 'eleven.png', 'ten.png'] ]

结论
我需要知道的是,如果RDD按原样分割,是什么控制同时处理多少个线程?它是核心数量,还是可以设置全局参数,因此它在每个分区(系统)上一次只处理4个?

1 个答案:

答案 0 :(得分:1)

  

数据从Spark中的RDD以什么顺序进行处理?

除非是一些边界情况,只有一个分区,否则顺序是任意的或不确定的。这取决于集群,数据和不同的运行时事件。

许多分区仅为给定阶段设置了整体并行度的限制,换句话说,它是Spark中最小的并行度单位。无论您分配多少资源,单个阶段都应该处理比当时更多的数据。当工人无法访问并且任务在另一台机器上重新安排时,可能会出现边界情况。

您可以想到的另一个可能的限制是执行程序线程的数量。即使您增加了分区数,单个执行程序线程也只会处理一个。

以上两者均未告诉您何时或何时处理给定的分区。虽然您可以在配置级别使用一些脏的,低效的和非便携式技巧(例如每个机器具有单个执行程序线程的单个工作程序),以确保在给定的机器上仅处理一个分区时一般有用。

根据经验,我会说Spark代码永远不会与执行它的地方有关。 API的一些低级方面提供了设置分区特定首选项的方法,但据我所知,这些不提供硬保证。

据说可以想到至少有几种方法可以解决这个问题:

  • 长期运行的执行程序线程,具有配置级别保证 - 如果Spark仅负责加载和保存数据,则可以接受
  • 控制GPU上排队作业的单例对象
  • 将GPU处理委托给确保正确访问的专业服务

一方面,您可能对Large Scale Distributed Deep Learning on Hadoop Clusters感兴趣,Command reference for the DPO3000大致描述了可适用的架构。