假设我们有一个RDD,它被多次使用。因此,为了一次又一次地保存计算,我们使用rdd.persist()方法保留了这个RDD。
因此,当我们持久化这个RDD时,计算RDD的节点将存储它们的分区。
现在假设,包含此持久RDD分区的节点失败,那么会发生什么?如何激发恢复丢失的数据?有复制机制吗?还是其他一些机制?
答案 0 :(得分:4)
当你做rdd.persist时,rdd没有实现内容。当您对rdd执行操作时,它会执行此操作。它遵循相同的懒惰评估原则。
现在,RDD知道它应该运行的分区以及与之关联的DAG。使用DAG,它完全能够重新创建物化分区。
因此,当一个节点发生故障时,驱动程序会在另一个节点中生成另一个执行程序,并为它提供它应该工作的数据分区以及与它关联的DAG。现在有了这些信息,它可以重新计算数据并实现它。
同时,RDD中的缓存数据不会拥有内存中的所有数据,它必须从磁盘中获取的丢失节点的数据将花费更多的时间。
在复制时,yes spark支持内存复制。您需要在保留时设置StorageLevel.MEMORY_DISK_2。
rdd.persist(StorageLevel.MEMORY_DISK_2)
这可确保数据被复制两次。
答案 1 :(得分: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