Apache spark 创建Spark作业的时间非常长,数据帧上有许多过滤条件

Apache spark 创建Spark作业的时间非常长,数据帧上有许多过滤条件,apache-spark,pyspark,Apache Spark,Pyspark,我有一个PySpark数据框,形状(1e10,14),我想用大约50个复合或语句对其进行过滤,即: sql_string = " (col1='val1' and col2=5) or (col1='val2' and col2=7) or (col1='val3' and col2=5) or ... " df_f = df.filter(sql_string) df_f.limit(1000).show() 如果这些单个OR语句的数量小于10,则会立即创建show方法的Spark作业。

我有一个PySpark数据框,形状
(1e10,14)
,我想用大约50个复合或语句对其进行过滤,即:

sql_string = "
(col1='val1' and col2=5) or 
(col1='val2' and col2=7) or
(col1='val3' and col2=5) or
...
"
df_f = df.filter(sql_string)
df_f.limit(1000).show()
如果这些单个OR语句的数量小于10,则会立即创建show方法的Spark作业。
然而,大约有15个ORs,创建Spark作业已经需要大约30秒。
在20个小时左右,创造任何火花工作的时间变得难以管理(超过几个小时)

从大约15个ORs开始,每隔几秒钟显示一次GC分配消息,即:

2020-05-04T09:55:50.762+0000: [GC (Allocation Failure) [PSYoungGen: 7015644K->1788K(7016448K)] 7266861K->253045K(21054976K), 0.0063209 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
看来有什么奇怪的事情发生了。感觉和这个问题类似,当一个人在Spark数据帧上循环时

该驱动程序有32GB RAM(使用10G)和4个内核(1个内核100%使用,其他接近0%)。 I/O几乎为零。
虽然一个核心上有100%的使用率,但集群认为它是非活动的,因为它在我设置的非活动时间之后关闭


以下是执行计划的链接:。

在此场景中,您使用复合OR语句基于多个硬编码值过滤数据帧,因此spark catalyst optimizer还必须逐个检查每个过滤器,并在执行每个OR语句后加载完整的数据帧

因此,当我们缓存数据帧时,它已经在内存中了,因此通过将缓存的数据帧传递给所有执行器,执行它会更快

对于大型数据帧,您可以尝试在mem和磁盘上持久化,这应该会给您带来您想要的性能提升,但如果这不起作用,您可以通过按col1过滤数据帧,然后按col2过滤已过滤的数据帧来改进查询。这将需要您实现一种基于逻辑的方法,以最小化对大数据的迭代


希望有帮助。

在此场景中,您使用复合OR语句基于多个硬编码值过滤数据帧,因此spark catalyst optimizer还必须逐个检查每个过滤器,并在执行每个OR语句后加载完整的数据帧

因此,当我们缓存数据帧时,它已经在内存中了,因此通过将缓存的数据帧传递给所有执行器,执行它会更快

对于大型数据帧,您可以尝试在mem和磁盘上持久化,这应该会给您带来您想要的性能提升,但如果这不起作用,您可以通过按col1过滤数据帧,然后按col2过滤已过滤的数据帧来改进查询。这将需要您实现一种基于逻辑的方法,以最小化对大数据的迭代


希望能有所帮助。

我最初来自Cloudera stack的经验,我倾向于使用镶木地板和kudu

尽管如此,以下内容尽管不确定你在问什么,但更像是观察:

  • 50个过滤器需要时间,没有过滤器在频谱的另一端,但在这种情况下,处理时间显然接近于零。或者加工成本更高

  • 下推从物理计划中很明显,现在是ORC处理的默认设置

  • ORC引擎做下推工作,所以你们观察到的执行器活动要少得多

  • 限制不能下推到数据库或拼花地板/orc

  • GC内容可以忽略

  • 我的整体看法:采用1e10垂直形状元素,在我看来没有什么不寻常之处


    第一次贴出的答案不正确。

    最初来自Cloudera stack的经验,我倾向于使用镶木地板和kudu

    尽管如此,以下内容尽管不确定你在问什么,但更像是观察:

  • 50个过滤器需要时间,没有过滤器在频谱的另一端,但在这种情况下,处理时间显然接近于零。或者加工成本更高

  • 下推从物理计划中很明显,现在是ORC处理的默认设置

  • ORC引擎做下推工作,所以你们观察到的执行器活动要少得多

  • 限制不能下推到数据库或拼花地板/orc

  • GC内容可以忽略

  • 我的整体看法:采用1e10垂直形状元素,在我看来没有什么不寻常之处


    第一次发布的答案不正确。

    如果可能,请尝试在运行筛选查询之前缓存数据帧。事实上,在筛选之前缓存df会使作业创建时间回到即时。为什么会这样?但是,这里提到的1e10数据集是更大的数据集的一部分,因此不可能再在内存中缓存。我只能将其保存在磁盘上,但我想从我所看到的.ORC文件格式中也会出现同样的问题?驱动程序并不是真正的问题。不过,我假设任务完成了。如何运行?如果可能,请尝试在运行筛选查询之前缓存数据帧。实际上,在筛选之前缓存df会使作业创建时间回到即时。为什么会这样?但是,这里提到的1e10数据集是更大的数据集的一部分,因此不可能再在内存中缓存。我只能将其保存在磁盘上,但我想从我所看到的.ORC文件格式中也会出现同样的问题?驱动程序并不是真正的问题。不过,我假设任务完成了。你跑得怎么样?谢谢!但让我困惑的是,没有缓存就不会创建任何火花作业。也就是说,遗嘱执行人甚至没有被使用。所以它不能被关联,因为我猜执行者的缓存?我还尝试了更大的数据集shape(>1e13,14),它仍然可以工作-没有OOM错误,尽管大数据集无法放入RAM。因此,你说WhistageCodegen无法优化or语句,将重新读取?@BluePhantom没有完全重新读取。从问题中的优化逻辑计划来看,它看起来并不是更好,批发性tagecodegen将多个运算符转换为一个单独的ja