有人声称,由于重新计算和容错性,Spark RDD必须是其输入的确定性函数,但也有经过认可的非确定性RDD,例如在SparkSQL或SparkML中。是否有关于如何安全使用不确定性的正式指导?
考虑这个带有钻石形DAG的Spark作业。
val bar = (rdd map f) zip (rdd map g)
bar.saveAsTextFile("outfile")
如果rdd
是不确定的(例如随机或时间戳记),outfile
会包含一致的数据吗?是否可能会重新计算zip的一个组件,而不会重新计算另一个组件?如果我们检查点或坚持使用rdd
,是否可以保证安全? local checkpoint够了吗?
答案 0 :(得分:1)
常规
以下是我的一些实际经验和经验:
如果您从Hive中的表/文件中读取数据,那么Spark将列出所有使用的文件以及该列表中证明了哪个节点的列表,因此如果重新进行计算,则重新计算将保持一致从头开始,即从HDFS / Hive中读取该数据子集。
如果使用随机函数,则我使用.cache或.persist来避免使用不同的路径逻辑重新计算。 当然,结合上述内容,如果在读取并必须从源获取数据后使用随机函数,则会得到不同的结果。见下文。
如果允许在处理的同时更新JDBC源并从中重新计算DAG,则从JDBC源读取内容将不能保证一致性/确定性结果。
检查点的作用
如果由于任何原因失败,从DAG一直返回到源的计算都是很昂贵的。在给定阶段执行的检查点将数据存储到磁盘-本地或HDFS,如果随后发生故障,则从该点开始重新计算,从而节省了时间。 DAG世系已损坏。
最后的笔记
如果重新计算是从JDBC源开始的,或者所使用的随机函数在舞台中进行处理时会影响随后已经处理的分区,该怎么办?我不能轻易证明这一点,但是我认为那些不适合“当前节点”重新处理的结果将被丢弃。否则,这是不现实的。
关于作者自己的答案,What is the difference between spark checkpoint and persist to a disk,应注意以下几点:“ ...几乎没有什么重要区别,但最根本的区别是沿袭发生的情况。持久性/缓存使沿袭保持完整,而检查点使沿袭中断...”。其他答案中的说法不正确。
答案 1 :(得分:0)
根据this post cache
,在persist
上使用checkpoint
,rdd
和persist(StorageLevel.DISK_ONLY)
将会有效地打破当前的作业,而checkpoint
会中断所有作业的沿袭(但不会清理文件)。我初步得出结论,在persist
或checkpoint
之后重试任务不会破坏数据一致性。 cache
操作不能保证一致性。
在persist
之前是否存在问题?如果rdd
分区包含独立的随机数据,则在单独的分区上重试任务没有问题。如果rdd
包含时间戳,则rdd
应该包含一个分区。
Checkpoint
。
Some transformations在RDD的顺序中引入了不确定性。如果您需要在RDD的重复使用副本之间保持顺序一致性(例如,由于zipWithIndex
),则沿袭最近的persist
或checkpoint
的世系不应包含任何订单-修改转换。