Spark应用程序中的持久计数器

时间:2017-08-31 18:23:13

标签: apache-spark pyspark apache-spark-sql spark-dataframe

我有一个Kafka服务器,每隔n分钟生成如下数据:

[('a', 123), ('b', 87), ('c', 101)]

我希望我的火花应用程序能够保留表格

的计数器

counter = {'a': 1, 'b': 0, 'c': 1}

其中字典(或任何其他适当的数据结构)值如果成对,则增加,例如, ('a', score),得分>例如,100。

下次我从Kafka使用数据时,如果(a, score)对再次获得分数> 100我希望counter['a']增加一个单位,使其等于2

2 个答案:

答案 0 :(得分:2)

您可以使用collections.Counter

data = [('a', 123), ('b', 87), ('c', 101)]

from collections import Counter    ​
mycounter = Counter()         # initiate the Counter

然后使用update方法增加计数:

# update the counter with your transformed data
mycounter.update({k: 1 if v > 100 else 0 for k, v in data})    
mycounter
# Counter({'a': 1, 'b': 0, 'c': 1})

第二次更新:

mycounter.update({k: 1 if v > 100 else 0 for k, v in data})
mycounter
# Counter({'a': 2, 'b': 0, 'c': 2})

答案 1 :(得分:1)

您可以将累加器与计数器一起使用。

构建累加器:

from collections import Counter

class CounterAccumulatorParam(AccumulatorParam):  
    def zero(self, value):  
        return {}
    def addInPlace(self, val1, val2):
        val1.update(val2)
        return val1

accum_counter = sc.accumulator(Counter(),CounterAccumulatorParam())

如果你想更新累加器的值,只需添加一个键值对:

accum_counter.add({key:num})

对于你的例子:

rdd_test = sc.parallelize([('a', 123), ('b', 87), ('c', 101)])

accum = sc.accumulator(Counter(),CounterAccumulatorParam())

def add_func(x):
    if x[1]>100:
        accum.add({x[0]:1})

rdd_test.foreach(lambda x: add_func(x))


accum.value
# Counter({'a': 1, 'c': 1})