在这种情况下,大文件会发生什么?
1)Spark从NameNode获取数据位置。因为根据NameNode的信息,数据大小太长,Spark是否会同时停止?
2)Spark根据数据节点块大小对数据进行分区,但是无法将所有数据存储到主存储器中。在这里,我们不使用StorageLevel。那么这里会发生什么呢?
3)Spark会对数据进行分区,一旦此主内存存储的数据将再次处理,一些数据将存储在主内存中。spark将从磁盘加载其他数据。
首先,Spark仅在调用动作(例如count
,collect
或write
)时才开始读取数据。调用动作后,Spark会在partitions中加载数据-同时加载的分区数取决于您拥有的可用核心数。因此,在Spark中,您可以想到1个分区= 1个核心= 1个任务。请注意,所有并发加载的分区都必须适合内存,否则您将获得OOM。
假设您有多个阶段,Spark然后从第一阶段开始仅在已加载的分区上运行转换。将转换应用于已加载分区中的数据后,它将输出存储为随机数据,然后在更多分区中读取。然后,它将转换应用于这些分区,将输出存储为shuffle-data,在更多分区中进行读取,依此类推,直到读取完所有数据。
[如果不应用任何转换,而仅执行例如count
,Spark仍将读取分区中的数据,但不会在集群中存储任何数据,如果再次执行count
,它将读取数据所有数据再次出现。为了避免多次读取数据,您可以调用cache
或persist
,在这种情况下,Spark will尝试将数据存储在群集中。在cache
上(与persist(StorageLevel.MEMORY_ONLY)
相同,它将所有分区存储在内存中-如果它不适合在内存中,您将得到一个OOM。如果调用persist(StorageLevel.MEMORY_AND_DISK)
,它将存储尽可能多的分区)内存,其余的将放置在磁盘上。如果数据不适合磁盘,则操作系统通常会杀死您的工作人员。
请注意,Spark具有自己的内存管理系统。如果您调用cache
或persist
,则分配给Spark作业的某些内存用于保存正在处理的数据,而某些内存用于存储。
我希望这个解释有帮助:)
这直接从Apache Spark常见问题解答(FAQ | Apache Spark)中引用