需求
zeppelin的pyspark中 DataFrame.groupBy(*cols).agg()操作大数据量会爆内存。
推荐用RDD.reduceByKey()但是这个只能对两列,以第一列为key,第二列为value。
而且在同一个task上,同partition的数据先是同key的valfue进行合并操作,以此大大减少后面shuff的数据量。
本来想实现select groupkey,count(value),count(distinct value) from table group by groupkey的sql语句,
但是spark-sql机制跟dataframe/rdd操作不一样,调优也是各种问题导致失败;
只得用dataframe的算子,但是到了数据量太大,groupby也是不行;
只得再想办法用RDD.reduceByKey
网上全是千篇一律的operator.add 操作,然后发现operator是一个运算模块,根本不是给PipelinedRDD的配套运算
实现 select key,count(value) from table group by key
rdd = sc.parallelize(List(("0", "v1"), ("0", "v2"), ("1", "v1"), (2, "v2")), 2)
result=rdd.countByKey()
print(result)
defaultdict(<type 'int'>, {u'2': 1, u'1': 1, u'0': 2})
注意:结果是是defaultdict,是输入的是两列,内部调用的是x[0].countByValue() ,即对相同key计算值出现总个数countByValue
经一亿条数据测试,countByKey()还是会内存不够,跟reduceByKey不同,换一种实现思路: