如果我有 5个节点的群集,则每个节点具有 1gb内存,现在我的数据文件为 10gb 分布在所有5个节点中,如果我触发
,则每个节点说2gbval rdd = sc.textFile(“ filepath”)
rdd.collect
会将负载数据触发到ram中,以及spark如何处理这种情况 它会立即拒绝还是对其进行处理。
答案 0 :(得分:1)
使用收集时,仅在驱动程序节点中将所有发送的数据收集为数组。 从这一点来看,分布火花和其他节点不起作用。您可以将其视为单台机器上的纯Java应用程序。
您可以使用spark.driver.memory
确定驱动程序的内存并要求10G。
从这一刻开始,如果您没有足够的内存来存储数组,则可能会出现OutOfMemory异常。
答案 1 :(得分:1)
首先让我们理解这个问题,@ intellect_dp,您有一个由5个节点组成的集群(这里的术语“节点”我假设机器通常包括硬盘,RAM,4核cpu等),现在每个节点具有 1 GB RAM ,并且您有10 GB的数据文件以某种方式分布,即2GB的数据驻留在每个节点的硬盘中。在这里,假设您正在使用HDFS,现在每个节点的块大小为2GB。
现在让我们打破这个:
由于在spark中进行惰性评估,只有在触发“ Action API”时,才将数据加载到RAM中并进一步执行。
在这里您是说您正在使用“收集”作为操作api。现在的问题是,RAM大小小于您的块大小,并且如果使用spark的所有默认配置( 1个块= 1个分区)处理它,并且考虑到将不再添加任何节点,那么在这种情况下,它将给您内存不足的异常。
现在的问题-使用给定的硬件配置,spark有什么方法可以处理这种大数据?
回答-是的,首先您需要设置默认的最小分区:
val rdd = sc.textFile(“ filepath”,n)
这里n是我默认的最小块分区,因为我们只有1gb的RAM,所以我们需要使其小于1gb,所以假设n = 4, 现在,因为您的块大小为2gb,并且块的最小分区为4:
每个分区的大小为= 2GB / 4 = 500mb;
现在spark将首先处理此500mb并将其转换为RDD,当下一个500mb出现时,第一个rdd将溢出到硬盘上(假设您已将存储级别设置为“ MEMORY_AND_DISK_ONLY” < / strong>)。
通过这种方式,它将使用给定的群集硬件配置来处理整个10 GB的数据文件。
现在,我个人不会为这种情况推荐给定的硬件配置, 因为它肯定会处理数据,但是缺点很少:
首先它将涉及多个I / O操作,从而使整个过程非常缓慢。
其次,如果在读取或写入硬盘时出现任何滞后,您的整个工作将被丢弃,您将对这种硬件配置感到沮丧。除此之外,您将永远无法确定会触发处理您的数据,并能够在数据增加时给出结果。
因此,请尽量减少I / O操作,并且 充分利用Spark的内存计算能力,并增加少量资源以提高性能。
答案 2 :(得分:0)
否则,性能会受到影响,我们将无法获得想要的速度。
Spark存储也只将结果存储在RDD中,所以我可以说结果将不是完整的数据,如果在表名中执行select *,那么在任何最坏的情况下,它都会以块的形式提供数据,它可以处理的数据...... < / p>