地图上镶木地板行组

时间:2019-03-20 15:02:29

标签: python apache-spark pyspark

我们有一个master-> detail数据集,该数据集由API访问,而明细数据则存储在HDFS的Parquet文件中。

主数据包含所有详细信息,以标识存储我们要查找的每一行数据的确切文件。当用户查询索引时,他们会收到返回的索引结果,通常分布在20k行左右的指针500个文件,每个行键将返回1个或更多行;通常,像这样的查询将为单个行键返回数千行。

环境:带有Python 3.6的PySpark 2.3.0

因为我们确切知道每个数据点位于哪个文件中,所以我一直在使用binaryFiles来读取各个Parquet文件,并将(文件名,字节)以及索引结果一起传递给映射器,广播给所有执行者。

# indexdf is the Pandas dataframe containing the index results, broadcast to all executors.
brdcst = sc.broadcast(indexdf)
sc.binaryFiles(",".join(pfileobj)).map(lambda x: self.processFile(x, brdcst)).collect()

此代码对于小文件来说效果很好,但是当文件变大时,返回结果时我要么超过2GB的Spark shuffle限制,要么超过Pickling最大可序列化的大小限制。

我的Parquet行组具有行键的统计信息,因此,如果我可以基于Parquet行组进行映射,则类似于binaryFiles,但具有(filename, rowgroup_stats, rowgroup_data)这样的数据集(大约),我想我会克服所有这些问题,并获得更好的启动并行化。

我应该考虑的想法或新方向?

在该项目开始时,我确实尝试将每个文件分别加载到Spark SQL中并进行联接,但是由于我没有跨文件并行化,所以它的速度很慢。我还尝试将所有文​​件加载到单个Spark SQL Dataframe中并加入,但是这项工作花费了10倍以上的时间,因为我失去了知道数据在哪里的优势,而不得不扫描整个数据帧。

0 个答案:

没有答案