Spark——广播变量(调优策略)

广播变量用来高效分发较大的对象,是一种调优策略

广播变量是每个Executor的内存中,只传一个变量副本,而不是对每一个task都传输一次大变量。也就是向所有工作节点发送一个较大的只读值,以供一个或多个Spark操作使用。

普通RDD操作

object JoinTest {
  def main(args: Array[String]): Unit = {
    val conf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("test")
    val sc = new SparkContext(conf)
    val rdd1 = sc.makeRDD(List((1, "a"), (2, "b"), (3, "c")))
    val rdd2 = sc.makeRDD(List((1, 11), (2, 22), (3, 33)))
    rdd1.join(rdd2).foreach(println)
  }
}

结果

(1,(a,11))
(3,(c,33))
(2,(b,22))

上面代码把k-v类型RDD中k相同的value放到元组中,但是join是一种宽依赖,所以会产生shuffle,并且join会有笛卡尔积,所以效率很低

使用广播变量进行优化

//使用广播变量优化
object BroadCast  {
  def main(args: Array[String]): Unit = {
    val conf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("test")
    val sc = new SparkContext(conf)
    val rdd1 = sc.makeRDD(List((1, "a"), (2, "b"), (3, "c")))
    val rdd2 = sc.makeRDD(List((1, 11), (2, 22), (3, 33), (3, 222)))
    //使用广播变量
     val broadcast: Broadcast[Array[(Int, Int)]] = sc.broadcast(rdd2.collect())
    //自定义一个累加器
    val myaccumulator = new Myaccumulator2()
    //使自定义累加器生效
    sc.register(myaccumulator)
    //这里用map,这时窄依赖,可以使整个过程没有shuffle,提高性能
    val value: RDD[(Int, util.ArrayList[Any])] = rdd1.map {
      case (k, v) => {
        for (t <- broadcast.value) {
          if (k == t._1) {
            //将key对应的value放到累计器中
            myaccumulator.add(t._2)
          }
        }
        //把自己的value放到累加器
        myaccumulator.add(v)
        //返回结果
        (k, myaccumulator.value)
      }
    }
    //打印
    value.foreach(println)
  }
}

上面需要用到的自定义的累加器Myaccumulator2

package spark.accumulator

import java.util

import org.apache.spark.util.AccumulatorV2

class Myaccumulator2 extends AccumulatorV2[Any, util.ArrayList[Any]] {
  val arrlist = new util.ArrayList[Any]()

  //是否是空
  override def isZero: Boolean = arrlist.isEmpty

  //拷贝出一份Myaccumulator
  override def copy(): AccumulatorV2[Any, util.ArrayList[Any]] = new Myaccumulator2()

  //初始化aeelist数组,使其为空
  override def reset(): Unit = arrlist.clear()

  //往arrlist增加数据
  override def add(v: Any): Unit =
  //把值大于5的放到arrlist

    arrlist.add(v)


  //把各个分区的arrlist合并到一起
  override def merge(other: AccumulatorV2[Any, util.ArrayList[Any]]): Unit =
    arrlist.addAll(other.value)

  //把合并好的arrlist发送给val值
  override def value: util.ArrayList[Any] = arrlist
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值