PySpark并行读取多个文件

时间:2018-09-05 07:32:25

标签: pyspark apache-spark-sql pyspark-sql parquet

我的项目中有以下要求,我们正在尝试使用PySpark进行数据处理。

我们过去通常以Parquet文件的形式接收每辆车的传感器数据,并以每辆车一个文件的形式接收传感器数据。该文件具有很多传感器,但是其结构化数据为Parquet格式。每个文件的平均文件大小为200MB。

假设我分批接收了以下文件并准备进行处理。

训练文件大小日期

X1 210MB 18年9月5日上午12:10

X1 280MB 18年9月5日下午5:10

Y1 220MB 18年9月5日上午4:10

Y1 241MB 18年9月5日下午6:10

在处理结束时,我需要从每个源文件或一个主文件中接收一个聚合的.csv文件,其中包含所有这些车辆的聚合数据。

我知道HDFS的默认块大小为128MB,每个文件将分为2个块​​。我可以知道如何使用PySpark满足此要求吗?是否可以并行处理所有这些文件?

请让我知道您的想法

3 个答案:

答案 0 :(得分:2)

我有一个类似的问题,看来我找到了一种方法: 1.获取文件列表 2.并行化此列表(在所有节点之间分配) 3.编写一个函数,该函数从分发到节点的大列表部分读取所有文件的内容 4.使用mapPartition运行它,然后以列表的形式收集结果,每个元素是每个文件的收集内容。 存储在AWS s3和json文件上的Fot文件:

def read_files_from_list(file_list):
#reads files from  list
#returns content as list of strings, 1 json per string ['{}','{}',...]
   out=[]
   for x in file_list:
      content = sp.check_output([ 'aws', 's3', 'cp', x, '-']) # content of the file. x here is a full path: 's3://bucket/folder/1.json'
      out.append(content)   
   return out #content of all files from the file_list as list of strings, 1 json per string ['{}','{}',...]


file_list=['f1.json','f2.json',...]
    ps3="s3://bucket/folder/"
    full_path_chunk=[ps3 + f for f in file_list] #makes list  of strings, with full path for each file
    n_parts = 100
    rdd1 = sc.parallelize(full_path_chunk, n_parts ) #distribute files among nodes
    list_of_json_strings = rdd1.mapPartitions(read_files_from_list).collect()

然后,如有必要,您可以创建如下的spark数据框:

rdd2=sc.parallelize(list_of_json_strings) #this is a trick! via http://spark.apache.org/docs/latest/sql-programming-guide.html#json-datasets
df_spark=sqlContext.read.json(rdd2)

read_files_from_list函数只是一个示例,应更改为使用python工具从hdfs读取文件。 希望这会有所帮助:)

答案 1 :(得分:0)

您可以将所有输入文件放在同一目录中,然后可以传递目录路径来触发。您也可以使用/data_dir/*.csv之类的通配符。

答案 2 :(得分:0)

我最近遇到了类似的情况。 您可以传递带有路径的 CSV 列表以激发读取 api,例如 spark.read.json(input_file_paths) (source)。这将加载单个数据帧中的所有文件,最终执行的所有转换将由多个执行程序并行完成,具体取决于您的 spark 配置。