我有一个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)
})
})
任何人都可以解释一下火花闭合是如何工作的吗?
非常感谢。
答案 0 :(得分:0)
因为你使用的是一个不能使用序列化的变量。当你定义一个本地元素时,你可以在RDD中使用它。