最有效的方法是并行加载spark中的许多文件?

时间:2016-06-29 21:31:27

标签: apache-spark pyspark google-cloud-dataproc

[Disclaimer: While this question is somewhat specific, I think it circles a very generic issue with Hadoop/Spark.]

我需要在Spark中处理大型数据集(~14TB)。不进行聚合,主要是过滤。给出~30k文件(250个部分文件,每个月10年,每个部分大约200MB),我想将它们加载到RDD / DataFrame中,并根据一些任意过滤器过滤掉项目。

为了使文件的列表更有效(我在google dataproc / cloud存储,所以驱动程序执行通配符是非常串行且非常慢),我预先计算文件名的RDD,然后将它们加载到RDD(我使用的是avro,但文件类型不应该相关),例如

#returns an array of files to load
files = sc.textFile('/list/of/files/').collect()  

#load the files into a dataframe
documents = sqlContext.read.format('com.databricks.spark.avro').load(files)

当我这样做时,即使在50个工作集群上,似乎只有一个执行程序正在执行读取文件的工作。我已经尝试过广播文件列表并阅读了十几种不同的方法,但我似乎无法解决这个问题。

那么,是否有一种从多个文件创建非常大的数据帧的有效方法?在创建此RDD时,如何最好地利用所有潜在的计算能力?

这种方法在较小的集合上运行得非常好,但是在这个大小的情况下,我看到了大量的症状,例如没有反馈的长时间运行的进程。是否有一些知识宝库 - 除了@ zero323 :-) - 在这个规模上优化火花?

1 个答案:

答案 0 :(得分:0)

列出3万个文件对于GCS来说不是问题-即使一次GCS列表请求一次最多列出500个文件,每个请求将花费1秒钟,所有30k文件将在一分钟左右的时间内被列出。在某些极端情况下,可能会有一些通配符模式使它变慢,但最近在GCS连接器globbing implementation中进行的优化可能会有所帮助。

这就是为什么它足以让您仅依赖默认的Spark API进行遍历:

s1=df['sequence'].isnull().groupby(df['claim']).cumsum()
df['sequence']=s1+df.groupby('claim')['sequence'].ffill()
df
Out[145]: 
    claim  diagnosis  sequence
0     100          1       1.0
1     100          2       1.0
2     100          3       2.0
3     100          4       3.0
4     105          1       1.0
5     105          2       2.0
6     105          3       2.0
7     105          4       3.0
8     111          1       1.0
9     111          2       2.0
10    111          3       3.0
11    111          4       4.0