Apache Spark:意外的过滤结果

时间:2015-05-04 00:17:26

标签: apache-spark filter rdd

我在本地模式下使用Apache Spark v 1.2。我创建了一个RDD并将其保存在内存中。 Spark Web UI显示该RDD的85%存储在内存中。我在RDD中有一个功能/变量,其值为0,1正如我通过运行下面的脚本获得的结果所示:

In[96]: flagged.map(lambda x:(x[14],1)).reduceByKey(lambda x,y:x+y).collect()

Out[96]: [(0, 637981), (1, 272958)]

当我执行flagged.count()时,数字是两个值的总和,即637981 + 272958 = 910939

现在当我运行基于此的过滤器时,我没有得到相同的计数:

In[97]:  flagged.filter(lambda x: x[14]==0).count()

Out[97]:  637344

In[97]:  flagged.filter(lambda x: x[14]==1).count()

Out[97]:  272988

我很难理解为什么从过滤的RDD产生的数字与reduceByKey方法的数字不匹配。

1 个答案:

答案 0 :(得分:0)

使用缓存类型MEMORY_AND_DISK

rdd.persist(org.apache.spark.storage.StorageLevel.MEMORY_AND_DISK)

我觉得这是一个错误,我执行了一个样本工作,看起来你是对的

  val count3 = sc.parallelize(1 to 1000000).map(r => {
    (new java.util.Random().nextInt(2), 1)
  })


 count3.reduceByKey(_+_).collect

res10:Array [(Int,Int)] = Array((0,500201),(1,499799))

 count3.filter(r => r._1==0).count

res13:Long = 499613

 count3.filter(r => r._1==1).count

res14:长= 500143

但后来我将代码更改为

 val count3 = sc.parallelize(1 to 1000000).map(r => {
    (new java.util.Random().nextInt(2), 1)
  }).persist()
count3.count  

请注意,我这次添加了持久性(我能够缓存此rdd的100%)

count3.reduceByKey(_+_).collect

res27:Array [(Int,Int)] = Array((0,500048),(1,499952))

 count3.filter(r => r._1==0).count

res28:Long = 500048

 count3.filter(r => r._1==1).count

res29:长= 499952

我认为您正在生成RDD然后将其保留,默认缓存类型为MEMORY_ONLY。现在问题是你只能在内存中缓存85%的rdd,这意味着剩下的15%将按需重新计算。如果在创建rdd时使用一些随机函数,则在重新计算期间可以更改15%的数据。