Spark从入门到精通7 -- Spark编程进阶

本文深入探讨Spark中的累加器、广播变量和分区操作,解析其工作原理、应用场景及代码实现。累加器用于并行计算中的共享变量,保证多线程操作的安全;广播变量用于提高大数据处理时的效率,减少网络传输;分区操作则针对特定变量优化,提升代码执行速度。

Spark编程进阶

累加器
介绍与使用场景

当我们在驱动器端声明一个变量时,如果我们在计算过程中需要对变量进行修改,这个时候不同的执行器拿到的当前变量的一个副本。类似于Java多线程场景下对共享变量的操作。所以累加器作为一个驱动器端声明的变量,能保证多个执行器端操作的时候是不会发生变量冲突的情况。就像是Java中的AtomicInteger一样。

但是累加器具有容错性,当我们某个执行器节点宕机后,我们在当前节点转换生成的RDD需要基于谱系图重新执行,这时如果我们在转换操作中使用了累加器,就会导致累加器重复计算。所以我们最好保证累加器不是发送在转换操作(map,filter)中,而是使用在行动操作中。例如foreach().

代码demo
val count = new LongAccumulator()
sc.register(count) //需要先注册到SparkContext中

println("before  isZero: "  +  count.isZero)
println("before  count: "  +  count.count)  //总共加了几个数字
println("before  avg: "  +  count.avg)  //数字的平均数
println("before  sum: "  +  count.sum)  //数字的和
/**
before  isZero: true
before  count: 0
before  avg: NaN
before  sum: 0
*/

val rdd = sc.textFile("path")

rdd.foreach(line => {
  if (line.contains("hello")) {
    count.add(5)
  }
})

println("after  isZero: "  +  count.isZero)
println("after  count: "  +  count.count)
println("after  avg: "  +  count.avg)
println("after  sum: "  +  count.sum)
/**
after  isZero: false
after  count: 8
after  avg: 5.0
after  sum: 40
*/
广播变量
介绍与使用场景

如果一个变量很大,需要被所有的执行器节点访问,但是只需要具有可读权限即可。对于这种情况,我们可以使用广播变量,通过将变量广播,广播后的变量会被发送到各个节点一次,作为只读值处理。使得执行器节点上访问该变量不再是通过传参的方式,大大节省了网络开销提升了代码执行效率。

代码demo
//将rdd进行广播
val broadcast_rdd = sc.broadcast(rdd)
//访问广播后的变量
broadcast_rdd.value
性能优化情况

没有广播的情况:通过网络传输把变量发送到每一个 Task 中,会产生4Number的数据副本,每个副本都会占用一定的内存空间,如果变量比较大,会导致则极易出现OOM
使用广播的情况:通过Broadcast把变量传输到Executor的内存中,Executor级别共享唯一的一份广播变量,极大的减少网络传输和内存消耗!

广播变量的生命周期默认与SparkContext一致,序列化级别 是MEMORY_AND_DISK的(首先优先放在内存中,如果内存不够才放在磁盘上),所以如果对太大的对象进行广播会产生较大IO压力

分区操作
介绍与使用场景

某些变量是不需要对于RDD的每条数据都计算一遍的。像数据库连接这种,只需要在每个分区初始化一次就可以。所以提供分区操作,在每个分区中操作一次后,相当于这个变量在分区中是成员变量,供分区中RDD的每个元素访问,大大提高代码效率。

代码demo
mapPartitions()    //先对分区进行迭代  然后对分区中元素迭代
mapPartitionsWithIndex()  //迭代中含有分区序号
foreachPartitions()   
rdd.filter(x => x != null).repartition(256).foreachPartition(partition => {
    ...
    //分区变量声明
    ...
    partition.foreach(pair => {
        //具体处理每一个元素
    }
}
数值RDD
API介绍
方法含义
count()元素个数
mean()平均值
sum()总和
max()最大值
min()最小值
variance()方差
sampleVariance()采样中计算出的方差
stdev()标准差
sampleStdev()采样的标准差
stats()将以上结果全部计算出来封装到对象中返回
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值