无法理解aggregateByKey和combineByKey的工作原理

时间:2016-02-02 19:59:37

标签: apache-spark pyspark

我是初学者,学习Apache Spark。目前我正在尝试使用Python学习各种聚合。

为了给我所面临的问题提供一些背景信息,我发现很难理解通过“status”计算订单数量的aggregateByKey函数的工作原理。

我正在关注ITVersity的YouTube播放列表,下面是我正在使用的代码和一些示例输出。

ordersRDD = sc.textFile("/user/cloudera/sqoop_import/orders")
for i in ordersRDD.take(10): print(i)

输出:
1,2013-07-25 00:00:00.0,11599,CLOSED
2,2013-07-25 00:00:00.0,256,PENDING_PAYMENT
3,2013-07-25 00:00:00.0,12111,完成
4,2013-07-25 00:00:00.0,8827,CLOSED
5,2013-07-25 00:00:00.0,11318,完成
6,2013-07-25 00:00:00.0,7130,完成
7,2013-07-25 00:00:00.0,4530,完成
8,2013-07-25 00:00:00.0,2911,加工
9,2013-07-25 00:00:00.0,5657,PENDING_PAYMENT
10,2013-07-25 00:00:00.0,5648,PENDING_PAYMENT

ordersMap = ordersRDD.map(lambda x: (x.split(",")[3], x))

输出:
(u'CLOSED',u'1,2013-07-25 00:00:00.0,11599,CLOSED')
(u'PENDING_PAYMENT',u'2,2013-07-25 00:00:00.0,256,PENDING_PAYMENT')
(u'COMPLETE',u'3,2013-07-25 00:00:00.0,12111,COMPLETE')
(u'CLOSED',u'4,2013-07-25 00:00:00.0,8827,CLOSED')
(u'COMPLETE',u'5,2013-07-25 00:00:00.0,11318,COMPLETE')
(u'COMPLETE',u'6,2013-07-25 00:00:00.0,7130,COMPLETE')
(u'COMPLETE',u'7,2013-07-25 00:00:00.0,4530,COMPLETE')
(u'PROCESSING',u'8,2013-07-25 00:00:00.0,2911,处理')
(u'PENDING_PAYMENT',u'9,2013-07-25 00:00:00.0,5657,PENDING_PAYMENT')
(u'PENDING_PAYMENT',u'10,2013-07-25 00:00:00.0,5648,PENDING_PAYMENT')

ordersByStatus = ordersMap.aggregateByKey(0, lambda acc, val: acc + 1, lambda acc,val: acc + val)
for i in ordersByStatus.take(10): print(i)

最终输出:
(u'SUSPECTED_FRAUD',1558)
(u'CANCELED',1428)
(u'COMPLETE',22899)
(u'PENDING_PAYMENT',15030)
(u'PENDING',7610)
(u'CLOSED',7556)
(u'ON_HOLD',3798)
(u'PROCESSING',8275)
(u'PAYMENT_REVIEW',729)

我难以理解的问题是:
1.为什么在2个lambda函数中采用的aggregateByKey函数作为参数?
2. Vizualize第一个lambda函数的作用是什么? 3. Vizualize第二个lambda函数的作用是什么?

如果你可以解释一下上面的问题以及aggregateByKey的工作方式,如果可能的话,用一些简单的方框图会很有帮助吗?也许是一些中间计算?

感谢您的帮助!

谢谢,
希夫

1 个答案:

答案 0 :(得分:4)

Spark RDD分为多个分区,因此当您对所有数据执行聚合功能时,首先会聚合每个分区内的数据(分区只是数据的一个细分)。然后,您需要告诉Spark如何聚合分区。

第一个lambda函数告诉Spark如何在遇到新值时更改运行计数(累加器)。由于您正在计算,您只需将1加到累加器即可。在一个切片中,如果运行计数当前为4并且添加了另一个值,则运行计数应为lambda acc, val: acc + 1 。所以,你的第一个lambda函数是:

5 + 7 = 12

第二个lambda函数告诉Spark如何将来自一个数据切片的运行计数与来自另一个数据切片的运行计数相结合。如果一个切片的计数为5且第二个切片的计数为7,则组合计数为lambda acc1, acc2: acc1 + acc2 。所以你的第二个函数会写得更好:

which node

剩下的唯一微妙之处在于,所有内容都是通过键和#34;基础。累加器(计数)因密钥而异。