scala对象成员如何使用spark rdd

时间:2017-08-03 03:30:44

标签: scala apache-spark closures

我有一个spark应用程序,输出结果为redis。

它在本地模式下工作正常,但无法将redisHost与我在纱线群集模式下分配的10.242.10.100的args(0)连接起来。

redisHost未更改127.0.0.1

object TestSparkClosure {
  val logger: Logger = LoggerFactory.getLogger(TestSparkClosure.getClass)
  var redisHost = "127.0.0.1"
  var redisPort = 6379

  def main(args: Array[String]) {
    val conf = new SparkConf().setAppName("TestSparkClosure")

    if (args.length > 0) {
      redisHost = args(0)
    } else {
      conf.setMaster("local")
    }
    val sparkContext = new SparkContext(conf)
    var rdd = getRdd(sparkContext)
    rdd.foreachPartition(partitionOfRecords => {
      logger.info("host:port:" + redisHost + ":" + redisPort.toString)
      val jedis = new Jedis(redisHost, redisPort)
      partitionOfRecords.foreach(pair => {
        val keystr = pair._1
        val valuestr = pair._2
        jedis.set(keystr, valuestr)
      })
    })
  }

  def getRdd(spark: SparkContext): RDD[(String, String)] = {
    val rdd = spark.parallelize(List("2017\t1", "2018\t2", "2017\t3", "2018\t4", "2017\t5", "2018\t6")).map(line => {
      val cols = line.split("\t")
      (cols(0), cols(1))
    })
    rdd.reduceByKey((x, y) => {
      ((x.toInt + y.toInt).toString)
    }, 3)
  }
}

当我用这样的局部变量替换redisHost时,它再次正常工作。

    var localRedisHost = redisHost
    rdd.foreachPartition(partitionOfRecords => {
      logger.info("host:port:" + localRedisHost + ":" + redisPort.toString)
      val jedis = new Jedis(localRedisHost , redisPort)
      partitionOfRecords.foreach(pair => {
        val keystr = pair._1
        val valuestr = pair._2
        jedis.set(keystr, valuestr)
      })
    })

任何人都可以解释一下火花闭合是如何工作的吗?

非常感谢。

1 个答案:

答案 0 :(得分:0)

因为你使用的是一个不能使用序列化的变量。当你定义一个本地元素时,你可以在RDD中使用它。