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

Posted

技术标签:

【中文标题】Spark 如何从故障节点恢复数据?【英文标题】:What does Spark recover the data from a failed node? 【发布时间】:2018-05-22 13:21:42 【问题描述】:

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

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

那么现在假设,包含这个 RDD 持久化分区的节点失败了,那么会发生什么? spark如何恢复丢失的数据?有没有复制机制?还是其他机制?

【问题讨论】:

同样的故障 Torrance 只在这里工作 【参考方案1】:

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

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

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

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

在复制时,是的 spark 支持内存复制。持久化时需要设置 StorageLevel.MEMORY_DISK_2。

rdd.persist(StorageLevel.MEMORY_DISK_2)

这可确保数据被复制两次。

【讨论】:

我认为 “现在 RDD 知道它应该在哪个分区上运行以及与之关联的 DAG。有了 DAG,它完全有能力重新创建物化分区。” 是正确的。运行时没有 RDD,而是一组作为 TaskSet 的任务。【参考方案2】:

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

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

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

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

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

【讨论】:

以上是关于Spark 如何从故障节点恢复数据?的主要内容,如果未能解决你的问题,请参考以下文章

Spark Streaming 容错改进与零数据丢失

Redis 宕机后,如何实现故障,快速自动恢复?

Spark Streaming metadata checkpoint

PostgreSQL 一主两备节点(两备节点为同步节点)故障恢复

Hadoop中的Namenode故障和恢复

服务器数据恢复异常关机导致Vsan逻辑架构出现故障,节点虚拟机文件丢失的数据恢复案例