Spark开发-广播变量

核心
1、什么是广播变量
2、为什么需要广播变量
3、案例

什么是广播变量
Spark有两种共享变量——累加器、广播变量。广播变量可以让程序高效地向所有工作节点发送一个较大的只读值,以供一个或多个Spark操作使用。

为什么需要广播变量
Spark中分布式执行的代码需要传递到各个Executor的Task上运行。对于一些只读、固定的数据(比如从DB中读出的数据),每次都需要Driver广播到各个Task上,这样效率低下。广播变量允许将变量只广播(提前广播)给各个Executor。该Executor上的各个Task再从所在节点的BlockManager获取变量,而不是从Driver获取变量,从而提升了效率。
一个Executor只需要在第一个Task启动时,获得一份Broadcast数据,之后的Task都从本节点的BlockManager中获取相关数据。
使用方法
1.调用SparkContext.broadcast方法创建一个Broadcast[T]对象。任何序列化的类型都可以这么实现。
2.通过value属性访问改对象的值(Java之中为value()方法)
3.变量只会被发送到各个节点一次,应作为只读值处理(修改这个值不会影响到别的节点)

案例
下面是一个wordCount的案例。代码可以查看之前的文章

我们写了一个这样的类,这个类主要实现了v1+v2这一步
Spark开发-广播变量_第1张图片

广播变量
Spark开发-广播变量_第2张图片

我们这里通过wd.value()获取广播的实例,在通过实例调用方法,
Spark开发-广播变量_第3张图片

但是通过运行我们可以发现,这里我们的程序出现了不能序列化的问题。

Exception in thread "main" java.io.NotSerializableException: com.xlucas.Words
Serialization stack:
    - object not serializable (class: com.xlucas.Words, value: com.xlucas.Words@23ba74fe)
    at org.apache.spark.serializer.SerializationDebugger$.improveException(SerializationDebugger.scala:40)
    at org.apache.spark.serializer.JavaSerializationStream.writeObject(JavaSerializer.scala:47)
    at org.apache.spark.broadcast.TorrentBroadcast$.blockifyObject(TorrentBroadcast.scala:203)
    at org.apache.spark.broadcast.TorrentBroadcast.writeBlocks(TorrentBroadcast.scala:102)
    at org.apache.spark.broadcast.TorrentBroadcast.(TorrentBroadcast.scala:85)
    at org.apache.spark.broadcast.TorrentBroadcastFactory.newBroadcast(TorrentBroadcastFactory.scala:34)
    at org.apache.spark.broadcast.BroadcastManager.newBroadcast(BroadcastManager.scala:63)
    at org.apache.spark.SparkContext.broadcast(SparkContext.scala:1326)
    at org.apache.spark.api.java.JavaSparkContext.broadcast(JavaSparkContext.scala:639)
    at com.xlucas.WordCount.main(WordCount.java:38)

如果需要解决这个问题那么应该怎么做呢??
如果你的Words不能序列化,也不想去序列化,建议新建一个类,这个类继承了Words这个类,在实现了序列化的接口
Spark开发-广播变量_第4张图片
这里我们的广播变量需要采用Word这个类了
这里写图片描述

这样运行就没有问题了

你可能感兴趣的:(spark)