使用两个RDDs apache spark

时间:2014-06-12 21:38:39

标签: scala apache-spark

我正在使用calliope即spark插件来连接cassandra。我创建了两个看起来像

的RDD

class A val persistLevel = org.apache.spark.storage.StorageLevel.MEMORY_AND_DISK val cas1 = CasBuilder.cql3.withColumnFamily("cassandra_keyspace", "cassandra_coulmn_family 1") val sc1 = new SparkContext("local", "name it any thing ") var rdd1 = sc.cql3Cassandra[SCALACLASS_1](cas1) var rddResult1 = rdd1.persist(persistLevel)

class B val cas2 = CasBuilder.cql3.withColumnFamily("cassandra_keyspace", "cassandra_coulmn_family 2") var rdd2 = sc1.cql3Cassandra[SCALACLASS_2](cas2) var rddResult2 = rdd2.persist(persistLevel)

以某种方式跟随使用其他2创建新RDD的代码库不起作用。是否有可能我们不能一起迭代2个RDD?

以下是无效的代码段 -

case class Report(id: Long, anotherId: Long)

  var reportRDD = rddResult2.flatMap(f => {
    val buf = List[Report]()
    **rddResult1.collect().toList**.foldLeft(buf)((k, v) => {
      val buf1 = new ListBuffer[Report]
      buf ++ v.INSTANCE_VAR_FROM_SCALACLASS_1.foldLeft(buf1)((ik, iv) => {
        buf1 += Report(f.INSTANCE_VAR_FROM_SCALACLASS_1, iv.INSTANCE_VAR_FROM_SCALACLASS_2)
      })
    })
  })

如果我替换粗体并初始化它就像 -

val collection = rddResult1.collect().toList

var reportRDD = rddResult2.flatMap(f => {
    val buf = List[Report]()
    **collection**.foldLeft(buf)((k, v) => {
      val buf1 = new ListBuffer[Report]
      buf ++ v.INSTANCE_VAR_FROM_SCALACLASS_1.foldLeft(buf1)((ik, iv) => {
        buf1 += Report(f.INSTANCE_VAR_FROM_SCALACLASS_1, iv.INSTANCE_VAR_FROM_SCALACLASS_2)
      })
    })
  })

它有效,有没有解释?

2 个答案:

答案 0 :(得分:5)

您正在将转化与动作混合。 rdd2.flatMap的关闭是在工作人员身上执行的,而rdd1.collect是一个'行动'}在Spark lingo中,将数据传递给驱动程序。所以,非正式地说,当你尝试对它进行flatMap时,你可以说数据不存在。 (我不太了解内部因素 - 确定根本原因)

如果你想在两个RDD上分布式操作,你应该使用其中一个连接函数(join,leftOuterJoin,rightOuterJoin,cogroup)加入它们。

E.g。

val mappedRdd1 = rdd1.map(x=> (x.id,x))
val mappedRdd2 = rdd2.map(x=> (x.customerId, x))

val joined = mappedRdd1.join(mappedRdd2)
joined.flatMap(...reporting logic..).collect

答案 1 :(得分:2)

您可以在应用程序中操作RDD。但是您无法在执行程序(工作节点)中操作RDD。执行程序无法提供驱动集群的命令。 flatMap内的代码在执行程序上运行。

在第一种情况下,您尝试在执行程序中操作RDD。我估计你会得到NotSerializableException,因为你甚至无法将RDD对象发送给执行者。在第二种情况下,将RDD内容拉到应用程序,然后将此简单List发送给执行程序。 (Lambda捕获会自动序列化。)