Spark 是如何从故障节点恢复数据的?

What does Spark recover the data from a failed node?

假设我们有一个RDD,它被多次使用。因此,为了一次又一次地保存计算,我们使用 rdd.persist() 方法持久化了这个 RDD。

所以当我们持久化这个 RDD 时,计算 RDD 的节点将存储它们的分区。

那么现在假设,包含这个RDD持久化分区的节点发生故障,那么会发生什么? spark 将如何恢复丢失的数据?有复制机制吗?或者其他一些机制?

当您执行 rdd.persist 时,rdd 不会具体化内容。当您对 rdd 执行操作时它会执行。它遵循相同的懒惰求值原则。

现在 RDD 知道它应该操作的分区以及与之关联的 DAG。使用 DAG 完全可以重新创建物化分区。

因此,当一个节点发生故障时,驱动程序会在其他某个节点中生成另一个执行程序,并在闭包中为它提供它应该在其上工作的数据分区和与其关联的 DAG。现在有了这些信息,它可以重新计算数据并将其具体化。

与此同时,RDD 中的缓存数据不会在内存中包含所有数据,它必须从磁盘中获取丢失节点的数据,这将花费更多时间。

关于复制,是的,spark支持内存复制。坚持的时候需要设置StorageLevel.MEMORY_DISK_2.

rdd.persist(StorageLevel.MEMORY_DISK_2)

这确保数据被复制两次。

我认为我能够理解 Spark 弹性的最好方式是当有人告诉我我不应该将 RDD 视为大型分布式数据数组时。

相反,我应该将它们想象成一个容器,其中包含有关从数据源转换数据所采取的步骤的说明,并且一次采取一个步骤,直到产生结果。

现在,如果您真的很关心在持久化时丢失数据,那么您可以指定要复制缓存数据。

为此,您需要 select 存储级别。所以而不是通常使用这个:

MEMORY_ONLY - Store RDD as deserialized Java objects in the JVM. If the RDD does not fit in memory, some partitions will not be cached and will be recomputed on the fly each time they're needed. This is the default level.
MEMORY_AND_DISK - Store RDD as deserialized Java objects in the JVM. If the RDD does not fit in memory, store the partitions that don't fit on disk, and read them from there when they're needed.

您可以指定要重新放置持久化数据

MEMORY_ONLY_2, MEMORY_AND_DISK_2, etc. -    Same as the levels above, but replicate each partition on two cluster nodes.

因此,如果节点出现故障,您将不必重新计算数据。

在此处检查存储级别:http://spark.apache.org/docs/latest/rdd-programming-guide.html#rdd-persistence