spark 获取广播变量_spark RDD持久化 共享变量 广播变量 | 星尘

本文介绍了Spark中RDD的持久化机制,通过cache()和persist()方法实现内存缓存,提高性能。同时,讨论了共享变量——广播变量和累加器的使用,广播变量用于减少大规模数据传输,累加器则提供在任务间累加的共享功能。
摘要由CSDN通过智能技术生成

Spark非常重要的一个功能特性就是可以将RDD 持久化在内存中,当对RDD执行持久化操作时,每个节点都会将自己操作的RDD的partition持久化到内存中,并且在之后对该RDD的反复使用中,直接使用内存缓存的partition,这样的话,对于针对一个RDD反复执行多个操作的场景,就只要对RDD计算一次即可,后面直接使用该RDD ,而不需要计算多次该RDD

巧妙使用RDD持久化,甚至在某些场景下,可以将spark应用程序的性能提升10倍。对于迭代式算法和快速交互式应用来说,RDD持久化,是非常重要的。

要持久化一个RDD,只要调用其cache()或者persist()方法即可。在该RDD第一次被计算出来时,就会直接缓存在每个节点中。而且Spark的持久化机制还是自动容错的,如果持久化的RDD的任何partition丢失了,那么Spark会自动通过其源RDD,使用transformation操作重新计算该partition。

cache()和persist()的区别在于,cache()是persist()的一种简化方式,cache()的底层就是调用的persist()的无参版本,同时就是调用persist(MEMORY_ONLY),将数据持久化到内存中。如果需要从内存中去除缓存,那么可以使用unpersist()方法。

Spark自己也会在shuffle操作时,进行数据的持久化,比如写入磁盘,主要是为了在节点失败时,毕淼需要重新计算的过程。

Persist.java

package com.starmcu.git.spark.java;

import org.apache.spark.SparkConf;

import org.apache.spark.api.java.JavaRDD;

import org.apache.spark.api.java.JavaSparkContext;

/**

* RDD持久化

*

*/

public class Persist {

public static void main(String[] args) {

System.out.println("妈蛋");

SparkConf conf =new SparkConf().setAppName("Persist").setMaster("local");

JavaSparkContext sc =new JavaSparkContext(conf);

//cache()或者persist()的使用,时候规则的

//必须在transformation或者textFile等创建了一个RDD之后,直接连续调用cache()或persist()才可以

//如果你先创建一个RDD,然后单独另起一行执行cache()或persist()是没有用的

//而且,会报错,大量的文件会丢失

JavaRDD lines =sc.textFile("C://1.txt").cache();

long time1 =System.currentTimeMillis();

long count =lines.count();

long time2 =System.currentTimeMillis();

System.out.println(time2-time1+"!");

long count2 =lines.count();

long time3 =System.currentTimeMillis();

System.out.println(time3-time2+"!!");

sc.close();

}

}

共享变量

通常情况下,当向Spark操作(如map,reduce)传递一个函数时,它会在一个远程集群节点上执行,它会使用函数中所有变量的副本。这些变量被复制到所有的机器上,远程机器上并没有被更新的变量会向驱动程序回传。在任务之间使用通用的,支持读写的共享变量是低效的。 尽管如此,Spark提供了两种有限类型的共享变量,广播变量和累加器。

AccumulatorTest.scala

package com.starmcu.git.spark.scala

import org.apache.spark.{SparkConf, SparkContext}

object AccumulatorTest {

def main(args: Array[String]): Unit = {

val conf = new SparkConf().setAppName("AccumulatorTest").setMaster("local")

val sc =new SparkContext(conf)

val sum =sc.accumulator(0)

val numberArray =Array(1,2,3,4,56)

val numbers =sc.parallelize(numberArray,1)

numbers.foreach(num => sum +=num)

print(sum.value)

}

}

AccumulatorTest.java

package com.starmcu.git.spark.java;

import org.apache.spark.Accumulator;

import org.apache.spark.SparkConf;

import org.apache.spark.api.java.JavaRDD;

import org.apache.spark.api.java.JavaSparkContext;

import org.apache.spark.api.java.function.VoidFunction;

import java.util.Arrays;

import java.util.List;

/**

* 累加变量

*

*

*/

public class AccumulatorTest {

public static void main(String[] args) {

SparkConf conf =new SparkConf().setAppName("Accumulator").setMaster("local");

JavaSparkContext sc =new JavaSparkContext(conf);

Accumulator sum =sc.accumulator(0);

List numberList = Arrays.asList(1,2,3,4,6);

JavaRDD numbers =sc.parallelize(numberList);

numbers.foreach(new VoidFunction() {

@Override

public void call(Integer integer) throws Exception {

//然后在函数内部,就可以对Accumulator变量,调用add()方法,累加值

sum.add(integer);

}

});

//在driver程序中,可以调用Accumulator的value()方法,获取其值

System.out.println(sum.value());

sc.close();

}

}

广播变量

Spark的另一种共享变量是广播变量。通常情况下,当一个RDD的很多操作都需要使用driver中定义的变量时,每次操作,driver都要把变量发送给worker节点一次,如果这个变量中的数据很大的话,会产生很高的传输负载,导致执行效率降低。使用广播变量可以使程序高效地将一个很大的只读数据发送给多个worker节点,而且对每个worker节点只需要传输一次,每次操作时executor可以直接获取本地保存的数据副本,不需要多次传输。

BroadcastVariable.scala

package com.starmcu.git.spark.scala

import org.apache.spark.{SparkConf, SparkContext}

object BroadcastVariable {

def main(args: Array[String]): Unit = {

val conf =new SparkConf().setMaster("local").setAppName("BroadcastVariable")

val sc = new SparkContext(conf)

val factor =3

val broadcastVariable = sc.broadcast(factor)

val numberArray = Array(1,2,3,45,6)

val numbers = sc.parallelize(numberArray,1)

val multipleNumber =numbers.map(num => num *broadcastVariable.value)

multipleNumber.foreach(num => print(num+"---"))

}

}

BroadcastVariable.java

package com.starmcu.git.spark.java;

import org.apache.spark.SparkConf;

import org.apache.spark.api.java.JavaRDD;

import org.apache.spark.api.java.JavaSparkContext;

import org.apache.spark.api.java.function.Function;

import org.apache.spark.api.java.function.VoidFunction;

import org.apache.spark.broadcast.Broadcast;

import java.util.Arrays;

import java.util.List;

/**

*

* 广播变量

*

*/

public class BroadcastVariable {

public static void main(String[] args) {

SparkConf conf =new SparkConf().setMaster("local").setAppName("BroadcastVariable");

JavaSparkContext sc =new JavaSparkContext(conf);

//在java中,创建共享变量,就是调用SparkContext的Broadcast方法

//获取的返回结果是Broadcast(T)类型

final int factor =3;

final Broadcast factorBroadcast =sc.broadcast(factor);

List numberList = Arrays.asList(1,24,5,7,8,90,3);

JavaRDD numbers = sc.parallelize(numberList);

//让集合中的每个数字,都乘以外部定义的那个factor

JavaRDD numbersMap = numbers.map(new Function() {

@Override

public Integer call(Integer v1) throws Exception {

//使用共享变量时,调用其value()方法,即可获取其内部分装的值

int factor =factorBroadcast.value();

return v1 * factor;

}

});

numbersMap.foreach(new VoidFunction() {

@Override

public void call(Integer integer) throws Exception {

System.out.println(integer);

}

});

sc.close();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值