java编写 SparkStreaming动态广播变量常见问题

在用java开发sparkstreaming项目的时候有些时候会感觉很别扭,因为spark是scala语言开发的,虽然用javaSpark的api已经很成熟,但是,相对而言,还是scala比较方便。

用java开始的时候刚开始还不是很习惯,这这那那的问题有很多,但是渐渐习惯以后,感觉还可以,因为java编程的话,对类型参数的要求严格,编译上有很多的帮助,对于编程语言学习真的有很大的帮助,该说不说java真的很重要,之前很不喜欢java的语言觉得太死板,不好运用,但是这次java开发经验真的对我来说成长真的是太大了,又让我重新认识了一遍java的编程魅力,废话说了一大堆,该说正文了:java sparkStreaming动态广播变量的运用。

//当然java开发经验不住,所以这次还是很浅的介绍一下,还在学习中

在用java编写spark程序的时候同理,sparkseesion创建等等一系列的操作这些步骤可以去看看别的博客里面介绍的很详细,然后创建跟kafka的链接我们这里用的是kafka的API,“KafkaUtils.createDirectStream”。当然这样创建DStream是不安全的,如果spark任务在计算的时候进行被kill或者被强制停止的时候数据会丢失,在下一章节中我们会讲到spark的检查点机制。

在spark程序中我们会多多少少的引入一些我们经常需要调用的一些变量数据进行计算,比如引入mysql的计算规则或者算法对象之类的,然而这些我们会需要进行更新,比如10秒或者1分钟进行重新获取并且实时更新到我们的spark任务当中怎么办, 那么我们就需要进行对广播变量进行更新,在这里我用的是java的api进行的编写,在写之前我也上网查阅了很多的资料进行测试,在本地运行的时候都可以更新成功,但是一到集群上面就会报错,比如广播变量获取失败,或者广播变量删除失败等等,因为广播变量之前需要对广播变量进行删除然后才能进行重新广播broadcastSchema.unpersist(true);里面的参数一定是true,底层默认的是false

广播变量就是将driver端的引用变量广播到各个Exector上面,如果不使用广播变量,在每个executor中有多少task就有多少变量副本。使用了广播变量,实际上就是为了减少executor端的备份,最终减少executor端的内存,也是对程序的优化。

然后我们如果跟网上学的将更新广播变量放在算子里面执行的话,会报错,广播变量时间超时。最后我将广播变量的操作放在了foreachRDD中如图所示

java编写 SparkStreaming动态广播变量常见问题_第1张图片

这里说在foreachRDD中执行更新广播变量的时是对rdd进行foreach的时候执行更新操作,并不是对rdd里面的数据进行遍历的时候进行更新,如果在对rdd里面数据进行遍历的时候进行更新操作的话,效果跟在其他算子里面更新广播变量是一样的。

这里再补充一个问题,就是广播变量的时候涉及到了线程安全的问题,所以在初始化广播变量的时候需要加上synchronized关键字。要不然会线程安全的错,更新广播变量的是就不需要了。

所以在也是一个开发中的经验,优化程序的一部分,本身实时处理数据就要求程序要有很高的处理性能,所以在做大数据sparkstreaming的时候广播变量的应用还是很有用的。这个问题也是卡了我很长时间,网上的资料大同小异,估计也会有很多人会遇到这样的问题,希望本片文章会帮到在运用广播变量的同僚。

 

你可能感兴趣的:(Spark)