Caching apachespark:缓存和分区

Caching apachespark:缓存和分区,caching,collections,apache-spark,rdd,Caching,Collections,Apache Spark,Rdd,情况是这样的:我有一个不断增长的数据集合,我希望在Hadoop集群中使用RDD处理这些数据 下面是一个简短的例子: val elementA = (1, Seq(2, 3)) val elementB = (2, Seq(1, 3)) val elementC = (3, Seq(1, 2)) val testRDD = sc.parallelize(Seq(elementA, elementB, elementC)). map(x => (x._1, x._2)).setNam

情况是这样的:我有一个不断增长的数据集合,我希望在Hadoop集群中使用RDD处理这些数据

下面是一个简短的例子:

val elementA = (1, Seq(2, 3))
val elementB = (2, Seq(1, 3))
val elementC = (3, Seq(1, 2))

val testRDD = sc.parallelize(Seq(elementA, elementB, elementC)).
    map(x => (x._1, x._2)).setName("testRDD").cache()

val elementD = (4, Seq(1, 3))
val elementD1 = (1, Seq(4))
val elementD2 = (3, Seq(4))

val testAdd = sc.parallelize(Seq(elementD, elementD1, elementD2)).
    map(x => (x._1, x._2)).setName("testAdd")

val testResult = testRDD.cogroup(testAdd).mapValues(x => (x._1 ++ x._2).flatten)
结果如下(元素的顺序可能不同):

以下是我的目标:

  • 我想
    .cache()
    在集群内存中缓存我的RDD
  • 我希望能够向现有RDD添加新元素
  • 以下是我得出的结论:

  • RDD中的每个分区都单独且完全地缓存(例如,我有一个包含100个元素和4个分区的集合,我调用了
    .cache().collect()
    cache().first()
    ,在第一种情况下得到了4个缓存分区,在第二种情况下得到了1个缓存分区)
  • testRDD.cogroup(testAdd)
    的结果是新的RDD,可以再次缓存,如果我们尝试使用
    var testRDD
    并调用
    testRDD=testRDD.cogroup(testAdd)
    ,我们将丢失到缓存数据的链接
  • 我知道,RDD最适合批处理应用程序,我在这里有这样一点:每个新元素的
    Seq()
    将根据其他元素的属性计算
  • 有没有办法修改当前RDD而不从缓存中删除它的所有元素


    我想做一种临时存储,并在达到临时存储的某些限制后将临时存储与当前存储合并…

    RDD是不可变的,因此不能向它们添加新元素。然而,您可以通过将原始RDD与新元素联合来创建一个新的RDD,类似于您对testResult RDD所做的操作

    如果您希望在更新时对新RDD使用相同的变量,那么可以对该RDD使用var而不是val。e、 g

    var testRDD=sc.parallelize(…)
    val testAdd=sc.parallelize(…)
    testRDD=testRDD.union(testAdd)
    testRDD.cache()

    这将创建一个连接两个原始RDD的沿袭。如果您在testRDD上调用union太多次,这可能会导致问题。要解决这个问题,您可以在testRDD被联合多次后调用它的检查点,比如说每10次更新。您也可以考虑在检查点上调用TESTRD的修复。
    使用此技术,添加到testRDD的所有元素都应保留在缓存中

    感谢您的回答,但这里还有一个问题-在已经缓存的元素中肯定会有一些更改(请参阅我的问题示例),如何使用
    var
    hepls-me?我可以在
    var testRDD
    上调用
    testRDD.cache()
    ,它会在操作后自动缓存我的更新吗?很难相信这种魔力……我认为每次添加(并集)更多元素时,您都需要调用
    testRDD.cache()
    ,这实际上会创建一个新的RDD。不,您不需要再次调用
    .cache()
    ,它将创建新的
    MapPartitionRDD
    (在我的例子中)。但是似乎您可以为您的
    var testRDD
    调用
    .cache()
    一次。好的,很高兴知道。就像我在回答中所说的,关注我们的谱系问题,并考虑调用<代码> TESTRDD。检查点()/<代码>和<代码> TESTRDD。重新划分(X)每多次迭代。是的,这是真的。另一种方法是保留对旧RDD的引用,并在联合后调用unpersist,以便RDD在联合时位于缓存中。e、 g.
    val oldTestRDD=testRDD
    (1, List(2, 3, 4))
    (2, List(1, 3))
    (3, List(1, 2, 4))
    (4, List(1, 3))