精神崩溃:RDD.zip()方法

sds*_*sds 35 apache-spark

我刚刚发现了这种RDD.zip()方法,我无法想象它的合同可能是什么.

当然,我明白它的作用.但是,我一直都是这样理解的

  • RDD 中元素顺序是无意义的概念
  • 分区数及其大小是仅供用户进行性能调整的实现细节

换句话说,RDD是(多)集合,而不是序列(当然,例如,Python中的一个AttributeError: 'set' object has no attribute 'zip')

我上面的理解有什么问题?

这种方法背后的理由是什么?

在琐碎的背景之外它是合法的a.map(f).zip(a)吗?

编辑1:

编辑2:回复说:

当您从另一个RDD计算一个RDD时,新RDD中的元素顺序可能与旧RDD中的元素顺序不对应.

这似乎暗示即使是微不足道a.map(f).zip(a)不能保证等同于a.map(x => (f(x),x)).zip()结果可重复的情况是什么?

Sea*_*wen 23

RDD总是无序的,这是不正确的.例如,如果RDD是sortBy操作的结果,则RDD具有保证的顺序.RDD不是一组; 它可以包含重复项.分区对调用者来说不是不透明的,可以进行控制和查询.许多操作确实保留了分区和顺序,例如map.这就是说我觉得有点容易意外地违反所zip依赖的假设,因为它们有点微妙,但它肯定有目的.

  • 你是说RDD还记得它通过`sortBy`?多长时间?是`map`保存的属性?`filter`?`flatMap`? (2认同)

Spi*_*lov 8

我使用(并推荐)的心智模型是RDD的元素有序的,但是当你从另一个RDD计算一个RDD时,新RDD中元素的顺序可能与旧RDD中的元素顺序不对应.

对于那些想要了解分区的人,我会说:

  1. RDD的分区有一个订单.
  2. 分区中的元素具有顺序.
  3. 如果您考虑使用其中元素的顺序"连接"分区(比如按顺序将它们"端对端"),则最终的整体排序对应于忽略分区的元素顺序.

但同样,如果您从另一个RDD计算一个RDD,则关于两个RDD的顺序关系的所有赌注都将关闭.

RDD类的几个成员(我指的是Scala API)强烈建议订单概念(与他们的文档一样):

collect()
first()
partitions
take()
zipWithIndex()
Run Code Online (Sandbox Code Playgroud)

一样Partition.index,以及SparkContext.parallelize()SparkContext.makeRDD()(两者都需要Seq[T]).

根据我的经验,这些"观察"顺序的方式给出了彼此一致的结果,并且在RDD和有序Scala集合之间来回转换的行为与您期望的一样 - 它们保留了元素的整体顺序.这就是为什么我说,在实践中,RDD有一个有意义的订单概念.

此外,虽然很明显很多情况下从另一个计算RDD 必须改变顺序,但根据我的经验,在可能/合理的情况下,往往会保留顺序.不重新分区且不从根本上改变元素集的操作尤其倾向于保持顺序.

但这让我想到了关于"合同"的问题,实际上文档在这方面存在问题.我还没有看到一个操作对元素顺序的影响很明显的地方.(OrderedRDDFunctions该类不计算,因为它指的是基于数据的排序,这可能与RDD中元素的原始顺序不同.同样是RangePartitioner类.)我可以看到这可能会导致您得出结论有没有元素顺序的概念,但我上面给出的例子使这个模型对我不满意.