spark-streaming 共享变量

来源:互联网 发布:乌斯特条干数据分析 编辑:程序博客网 时间:2024/05/06 12:33

有这样一个需求,我需要在每次的Job中,都需要广播一次,广播的数据是当前时间时,redis中已经存在的logid。

spark共享变量

spark因为是分布式的内存计算系统,所以没有公共变量一说,每个executor都会把程序中的参数,变量保存一个副本。而你如果使用公共变量,spark提供了一个共性变量叫broadcast。刚好符合我们的要求,代码如下:

val existsLogids = LogExcuter.getAllLogId(System.currentTimeMillis())      var broadcastList = ssc.sparkContext.broadcast(existsLogids)      values.filter {        case (key, _) => {          (key % Config.sample == 0 || (wf == 0 && broadcastList.value.contains(key.toString)))        }      }.foreachRDD{...}

广播Java.util.Set对象

 @Override  public Set<String> zrangeByScore(final String key, final double min, final double max) {    return new JedisClusterCommand<Set<String>>(connectionHandler, maxAttempts) {      @Override      public Set<String> execute(Jedis connection) {        return connection.zrangeByScore(key, min, max);      }    }.run(key);  }

JedisCluster提供的zrangeByScore返回的对象是java.util.Set,这个对象广播的时候,executor得到的是null。是因为该对象不是immutable,无法被广播。所以需要进行如下操作:

def zrangeByScore(score: Long): Set[String] = {    val logids: java.util.Set[String] = client.zrangeByScore(key, 0, score)    logids.asScala.toSet  }

转换为scala.collect.immutable.Set对象,这样就可以用如下代码广播出去了。

一次性?

数据是广播出去,但是后续的Job中的数据跟第一次得到的数据是一样的,说明它不是每次都更新数据,而我们的目标是要求filter操作前都要得到最新的数据。后来查了原因是,广播数据是被缓存了,如果已经有该变量的数据,就不会重新获取。所以,我显式的清除缓存,重新广播

val existsLogids = LogExcuter.getAllLogId(System.currentTimeMillis())      var broadcastList = ssc.sparkContext.broadcast(existsLogids)      values.foreachRDD { rdd => {}        if (wf == 0) {          println("rebroadcast")          broadcastList.unpersist()          broadcastList = ssc.sparkContext.broadcast(LogExcuter.getAllLogId(System.currentTimeMillis()))        }      }      values.filter {        case (key, _) => {          //能被抽样系数整除或者已经存在的logid          (key % Config.sample == 0 || (wf == 0 && broadcastList.value.contains(key.toString)))        }      }.foreachRDD{...}

checkpoint冲突

上面修改完成后,运行后发现和checkpoint冲突,因为我们程序设置了checkpoint,做故障恢复的,但是现在冲突,我先把下面的代码注释了。

`
ssc.checkpoint(upCheckPointPath)

然后我们的程序成功的运行了,而且实时的广播最新的数据。

总结

第一次使用广播变量,踩了不少坑,总算搞定。不过还有一个坑,就是如何兼容checkpointbroadcastList.unpersist()的操作。后续再研究一下。

0 0
原创粉丝点击