【问题标题】:Apache Spark RDD cache and Lineage confusionApache Spark RDD 缓存和 Lineage 混淆
【发布时间】:2015-04-10 21:30:04
【问题描述】:

我用一些随机数学值填充 RDD:

val itemFactors = rddItems.mapValues(newFactors => 
    Vector(Array.fill(2){math.random})
)

然后我将该 RDD 加入到其他 RDD 并缓存它:

val finalRDD = itemFactors.join(rddItemsUsers).map{
    case(itemid, (itemVector, ((userid, rating), userVector))) => 
        (itemid, itemVector, userid, userVector, rating)}.cache

然后我对finalRDD中保存的数据进行计算:

sqrt(finalRDD.aggregate(0.0)((accum, item) => 
    accum + pow(item._5 - item._4.dot(item._2), 2), _ + _) / finalRDD.count)

我从控制台反复调用代码的最后一部分sqrt(...),每次我得到不同的结果 - 这是不希望的,因为我没有改变任何东西!这可以通过 2 种方式进行补救(即,使我得到一致的结果):

  • 我可以用固定数字填充数组,而不是用itemFactors 初始化math.random,例如1.0

  • 我可以itemFactors.cache

现在,我了解到,由于血统,每次调用 itemFactors 时,它都会调用 math.random 并创建一个新数字 - 因此,这将影响我的计算。这就是为什么在填充数组时使用固定数字会产生一致的结果。

但是,最大的问题和我不明白的一点是:我正在缓存 finalRDD,这是计算所执行的,因为它由 itemFactors 组成,所以肯定没关系itemFactor 的数组被填充了,因为节点只被访问过一次?我以为我开始掌握传承;但是,这让我很震惊。

【问题讨论】:

  • cache() 不能保证它总是被缓存——例如你有足够的内存来保存它吗?它的缓存百分比是多少?如果你丢失了一个块,它也会重新计算。
  • 不太清楚如何检查,但我检查了getStorageLevel,我得到:StorageLevel(false, true, false, true, 1)。如果我这样做getStorageLevel.description,我会得到:Memory Deserialized 1x ReplicatedgetStorageLevel.useMemory 返回True
  • 你能把它做成一个可重现的例子吗?我不知道rddItemsrddItemsUsers 中有什么。可能是侏儒。
  • 您可以在 UI 的存储选项卡上查看缓存的分数。
  • 我将尽快制作一个可重现的示例。感谢您的 UI 提示。

标签: apache-spark rdd


【解决方案1】:

如果您的缓存无法装入内存,则会根据 LRU 策略丢失。

为避免这种情况,您可以使用带有参数的持久化,如图所示

val result = input.map(x => x*x)
result.persist(MEMORY_ONLY)

MEMORY_ONLY - 将 RDD 作为反序列化的 Java 对象存储在 JVM 中。如果 RDD 不适合内存,则某些分区将不会被缓存,并且会在每次需要时重新计算。这是默认级别。

MEMORY_AND_DISK 将 RDD 作为反序列化的 Java 对象存储在 JVM 中。如果 RDD 不适合内存,请将不适合的分区存储在磁盘上,并在需要时从那里读取它们。

MEMORY_ONLY_SER 将 RDD 存储为序列化的 Java 对象(每个分区一个字节数组)。这通常比反序列化对象更节省空间,尤其是在使用快速序列化程序时,但读取时更占用 CPU。

MEMORY_AND_DISK_SER 类似于 MEMORY_ONLY_SER,但将不适合内存的分区溢出到磁盘,而不是在每次需要时即时重新计算。

DISK_ONLY 仅将 RDD 分区存储在磁盘上。 MEMORY_ONLY_2、MEMORY_AND_DISK_2 等。与上述级别相同,但在两个集群节点上复制每个分区。

OFF_HEAP(实验性)在 Tachyon 中以序列化格式存储 RDD。与 MEMORY_ONLY_SER 相比,OFF_HEAP 减少了垃圾收集开销,并允许执行器更小并共享内存池,使其在具有大堆或多个并发应用程序的环境中具有吸引力。此外,由于 RDD 驻留在 Tachyon 中,因此执行程序的崩溃不会导致丢失内存中的缓存。在这种模式下,Tachyon 中的内存是可丢弃的。因此,Tachyon 不会尝试重建它从内存中驱逐的块。

Refer to this link for more documentation

【讨论】:

    猜你喜欢
    • 2020-12-18
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    • 2016-11-29
    • 2014-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多