Spark Streaming - 计算状态中的不同元素

时间:2017-03-07 10:03:36

标签: python scala apache-spark spark-streaming spark-dataframe

我有一个带有键值对VideoID-UserID的dstream,通过VideoID计算一个不同的UserID组的好习惯是什么?

// VideoID,UserID
foo,1
foo,2
bar,1
bar,2
foo,1
bar,2

如上所述,我想通过随时删除多余的foo,1bar,2来获取VideoID-CountUserID,因此结果应为:

foo: 2
bar: 2

换句话说,我想在内存中保存一个大的状态数据集。当新一批dstream到达时,将其与数据集进行比较,以计算每个视频的不同用户。

怎么做?

我正在使用Spark 1.6,但接受了转发版本的答案。 Python代码,如果可能的话。

2 个答案:

答案 0 :(得分:1)

为了获得按视频ID分组的不同用户ID计数,请考虑使用 aggregateByKey 。对不起,这是Scala,所以你必须翻译。

val rdd = sc.textFile("your_file.txt")

val initialSet = Set.empty[Int]
val addToSet = (s: Set[Int], v:Int) => s + v
val mergeSets = (s1: Set[Int], s2: Set[Int]) => s1 ++ s2

val distinctValSets = rdd.aggregateByKey(initialSet)(addToSet, mergeSets)
val distinctValCountd = rdd.map({case(k,s) => (k,s.size)})

初始集是聚合对象的初始值,addToSet和mergeSets指定如何向集合添加值并根据键合并不同的集合。这应该为您提供与每个视频相关联的不同数量的用户,并且比reduceByKey和groupByKey更便宜(空间)。

答案 1 :(得分:0)

  val rdd1 = sc.parallelize(Seq(("foo", 1),("foo", 2),("foo", 1)))
  rdd1.groupByKey.mapValues(x=>x.toSet.toSeq).flatMapValues(x=>x).collect