我正在学习Spark,并正在学习教程。在练习中,我尝试对数据集进行一些分析。该数据集的每一行都有数据,例如:
userid | age | gender | ...
我有以下代码:
....
under_age = sc.accumulator(0)
over_age = sc.accumulator(0)
def count_outliers(data):
global under_age, over_age
if data[1] == '0-10':
under_age += 1
if data[1] == '80+':
over_age += 1
return data
data_set.map(count_outliers).collect()
print('Kids: {}, Seniors: {}'.format(under_age, over_age))
我发现必须使用方法“ .collect()”来使此代码起作用。也就是说,不调用此方法,代码将不会计算两个累加器。但据我了解,“。collect()”用于将整个数据集存储到内存中。为什么在这里有必要?与懒惰的评价有关吗?请告知。
答案 0 :(得分:2)
是的,这是由于懒惰的评估所致。
在执行collect
之类的action之前,Spark不会计算任何内容,并且累加器只会作为该计算的副作用而更新。
Transformations,例如map
定义了需要完成的工作,但是只有在触发了通过转换“拉动”数据的操作后,才执行该工作。
这在documentation中有描述:
累加器不会更改Spark的惰性评估模型。如果在RDD上的操作中对其进行更新,则仅当将RDD计算为操作的一部分时才更新它们的值。因此,当在诸如map()的惰性转换中进行累加器更新时,不能保证会执行更新。
注意以下几点也很重要:
在转换中,用户应注意,如果重新执行任务或工作阶段,则可能不止一次应用每个任务的更新。
因此您的累加器不一定会给出正确的答案;他们可能会夸大总数。