比较Spark中的两种不同方法:用于减少和排序

时间:2016-08-15 14:23:07

标签: pyspark rdd

假设我有以下RDD:

alist = [('a',[['1',2]]),('b',[['2',3]]),('b',[['8',5]]),('b',[['8',5]]),('c',[['4',22]]),('a',[['5',22]])]
anRDD = sc.parallelize(alist)

我的任务是从每个字符串字母获取具有最高int值的列表(列表的索引1)。如果有大量数据和许多不同的密钥(字符串字母),建议采用以下哪种方法?

方法1:

import operator

def sortAndTake(alistoflists):
    alistoflists.sort(key=operator.itemgetter(1),reverse=True)
    return alistoflists[0]

reducedRDD = anRDD.reduceByKey(lambda a,b:a+b)
finalRDD = reducedRDD.map(lambda x: (x[0],sortAndTake(x[1])))
finalRDD.collect()

方法2:

def partitioner(n):
    def partitioner_(x):
        return portable_hash(x[0]) % n
    return partitioner_

def sortIterator(iterator):
    oldKey = None
    cnt = 0
    for item in iterator:
        if item[0] != oldKey:
            oldKey = item[0]
            yield item

partitioned = anRDD.keyBy(lambda kv:(kv[0],kv[1][0][1]))

partitioned.repartitionAndSortWithinPartitions(
                                 numPartitions=2,
                                 partitionFunc=partitioner(2),ascending=False)
           .map(lambda x: x[1])
           .mapPartitions(sortIterator)

(方法2的灵感来自我之前提出的问题的接受答案(通过零323):Using repartitionAndSortWithinPartitions

根据我对第一种方法的理解,如果我们得到了一个巨大的不同键值,reduceByKey中的工作人员之间会有很多改组,这可能会使方法2变得更快(我不确定是否相同在方法2中使用repartitionAndSortWithinPartitions时发生。

有什么见解?谢谢:))

1 个答案:

答案 0 :(得分:2)

  

我的任务是从每个字符串字母获取具有最高int值的列表(列表的索引1)。

如果是这种情况,两种方法效率都很低。而只是reduceByKeymax

from operator import itemgetter
from functools import partial

anRDD.mapValues(itemgetter(0)).reduceByKey(partial(max, key=itemgetter(1)))

关于两种提议的方法:

  • 两者都会混合相同数量的数据。
  • 第一个效率较低groupByKey