几个字段的Spark组在同一个RDD上多次

时间:2016-02-24 14:15:27

标签: optimization apache-spark group-by aggregate pyspark

我的数据以csv格式存储,标题在column_names变量中提供。

我编写了以下代码,将其读入python词典RDD

rdd=sc.textFile(hdfs_csv_dir)\
.map(lambda x: x.split(','))\
.filter(lambda row: len(row)==len(column_names))\
.map(lambda row: dict([(column,row[index]) for index,column in enumerate(column_names)]))

接下来,我编写了一个函数,根据列名

计算列值的组合
import operator
def count_by(rdd,cols=[]):
    '''
    Equivalent to:
     SELECT col1, col2, COUNT(*) FROM MX3 GROUP BY col1, col2;
    But the number of columns can be more than 2
    '''
    counts=rdd.map(lambda x: (','.join([str(x[c]) for c in cols]), 1))\
    .reduceByKey(operator.add)\
    .map(lambda t:t[0].split(',')+[t[1]])\
    .collect()
    return counts

我正在多次运行count_by,在同一rdd上有很多不同的参数。

优化查询并使其运行得更快的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

首先,您应该缓存 RDD(通过调用cachedRdd = rdd.cache()),然后多次将其传递到count_by,以防止Spark为每个操作从磁盘加载它。在缓存的RDD上操作意味着数据将在首次使用时加载到内存中(首次调用count_by),然后从内存中读取后续调用。

您还应该考虑使用Spark DataFrame API而不是较低级别的RDD API,因为:

  • 您似乎用SQL表达了您的意图,DataFrame API允许您实际使用这样的方言
  • 使用DataFrames时,Spark可以执行一些额外的优化,因为它可以更好地理解你想要做什么,它是否可以设计实现它的最佳方法。类似SQL的方言很有效 - 你只说你想要的,而不是如何得到它,这让Spark有更多的优化自由