我正在寻找一种处理RDD列表的方法,同时最大限度地减少我需要执行的shuffle数量。
我有一个巨大的RDD,我已将其分解为单个桶并用于内部比较,以便进行内部比较
我到目前为止的基本想法是:
val r:RDD[Int, T]
val buckets = List(0 to n).map(a => r.filter(key == a))
buckets.map(_.cartesian().map(//internal comparison))
但后来我迷失了,因为如果我按照buckets.map(_.reduce(//reduction))
的方式做一些会引发大量洗牌的事情会让我感到效率低下,特别是考虑到我最终会想要减少结果所有这些减少。
有没有人对我如何解决这个问题有任何建议?
编辑:
我的总体目标是将RDD中的所有值与智能算法进行比较,而不是简单的笛卡尔算法。
基本思想是这些值是bucketized,以保证某些存储桶与彼此不相似,所以我只需要比较可能彼此相似的存储桶。
现实生活中的水桶应该是这样的:
val partitions:List[List[Int]] = clusterSimilarBuckets()
val buckets = partitions.map(a => r.filter{case(key, v) =. a.contains(key)})
答案 0 :(得分:0)
我的猜测是你正试图围绕Hash join的概念开展工作。
我的解决方案是通过基于您的存储桶算法的自定义分区程序进行重新分区(如果您计划减少分区数量,甚至可以更好地使用合并)。如果您打算使用相同的存储桶进行多次比较,我会考虑复制存储桶。考虑到这一步确实涉及一些改组。
在此之后,您可以使用mapPartitions运行一个昂贵的算法来比较分区中的每个元素,因为上一步所有元素都来自类似的桶。
答案 1 :(得分:0)
您还应该考虑使用Locality Sensitive Hashing来适应您的用例,因为它使用了多个哈希,因此两个元素很可能属于同一个存储桶。对LSH的更好解释是chapter 3 of Mining Massive Datasets book。快速谷歌搜索也显示LSH implementation for Spark。