当文件无法适应spark的主内存时,spark如何读取大文件(petabyte)

Arp*_*Rai 9 partition apache-spark rdd

在这些情况下,大文件会发生什么?

1)Spark从NameNode获取数据的位置.Spark会在同一时间停止,因为根据NameNode的信息,数据大小太长了吗?

2)Spark根据datanode块大小进行数据分区,但是所有数据都不能存储到主存储器中.这里我们没有使用StorageLevel.那么这里会发生什么?

3)Spark对数据进行分区,一旦主存储器的数据再次处理,一些数据将存储在主存储器上,spark将从光盘加载其他数据.

Gle*_*olt 42

首先,Spark只在调用动作(如count,collectwrite)时才开始读取数据.调用操作后,Spark会加载分区中的数据 - 并发加载的分区数取决于您可用的核心数.所以在Spark中你可以想到1个分区= 1个核心= 1个任务.请注意,所有并发加载的分区必须适合内存,否则您将获得OOM.

假设您有几个阶段,Spark然后仅在加载的分区上运行第一阶段的转换.一旦它对已加载分区中的数据应用了转换,它就将输出存储为shuffle-data,然后读入更多分区.然后它在这些分区上应用转换,将输出存储为shuffle-data,读入更多分区等等,直到读取完所有数据.

如果您不应用转换但仅执行例如a count,则Spark仍会读取分区中的数据,但它不会在群集中存储任何数据,如果count再次执行,它将再次读入所有数据.为避免多次读取数据,您可能会调用cachepersist在哪种情况下Spark 尝试将数据存储在您的群集中.打开cache(这与persist(StorageLevel.MEMORY_ONLY)它将所有分区存储在内存中相同 - 如果它不适合内存,你将获得一个OOM.如果你调用persist(StorageLevel.MEMORY_AND_DISK)它将尽可能多地存储在内存中,其余的将被放在磁盘上如果数据不适合磁盘,操作系统通常会杀死你的工作人员.

请注意,Spark有自己的小内存管理系统.您分配给Spark作业的一些内存用于保存正在处理的数据,如果您调用cache或,则某些内存用于存储persist.

我希望这个解释有帮助:)

  • @devesh 使用 `StorageLevel.DISK_ONLY` 肯定会影响性能!我只是提到它,因为问题是“StorageLevel.MEMORY_AND_DISK”是否是_only_选项,但事实并非如此:) (3认同)
  • 标准文本中未很好解决的出色答案! (2认同)

Swa*_*shi 5

这是直接引用自 Apache Spark FAQ ( FAQ | Apache Spark )

我的数据是否需要适合内存才能使用 Spark?

不可以。如果数据不适合内存,Spark 的操作符会将数据溢出到磁盘,使其能够在任何大小的数据上运行良好。同样,不适合内存的缓存数据集要么溢出到磁盘,要么在需要时动态重新计算,这取决于 RDD 的存储级别。

在 Apache Spark 中,如果数据不适合内存,那么 Spark 只是将该数据持久化到磁盘。

Apache Spark 中的persist 方法提供了六个持久化存储级别来持久化数据。

MEMORY_ONLY, MEMORY_AND_DISK, MEMORY_ONLY_SER 
(Java and Scala), MEMORY_AND_DISK_SER 
(Java and Scala), DISK_ONLY, MEMORY_ONLY_2, MEMORY_AND_DISK_2, OFF_HEAP.
Run Code Online (Sandbox Code Playgroud)

OFF_HEAP 存储正在试验中。