Spark的学习总结

理论知识

RDD及其特点

1、RDD是Spark的核心数据模型,是一个抽象类,是一个弹性是分布式数据集。
2、RDD在抽象上来说是一种元素的集合,包含了数据。它是分为多个分区,每个分区分布在集群的不同的节点上,从而让RDD中的数据可以被并行操作。
3、RDD通常通过hadoop上的文件,即hdfs上的文件或者hive表,来进行创建,有时也可以通过应用程序创建。
4、RDD最重要的特性就是提供了容错性,可以自动从节点失败中恢复过来。即如果某个节点上的RDDpartition因为节点故障,导致数据丢了,那么RDD会自动通过自己的数据来源重新计算(即RDD之间有血缘关系)
5、RDD的数据默认是存放在内存中的,但是在资源不足时,Spark会自动将RDD数据写入磁盘。(弹性)

RDD的创建

进行Spark核心编程第一步就是创建一个初始的RDD。该RDD通常就代表包含了Spark应用程序的输入源数据,然后通过Spark Core提供的Transtormation算子,对其RDD进行转换,来获取其他的RDD。

Spark Core提供了三种创建RDD的方式:
1、使用程序中的集合创建RDD(主要用于测试)

List<Integer> numbers = Arrays.aslist(1,2,3,4,5,6,7)
JavaRDD<Integer> numbersRDD = sc.parallelize(numbers)

2、使用本地文件创建RDD(主要用于临时性处理大量数据文件)

SparkSession spark = SparkSession.builder().master("local[*]").appName("WordCount").getOrCreate();
JavaRDD<String> lines = spark.read().textFile("D:\\file.txt").javaRDD();

3、使用HDFS文件创建RDD(生产环境的常用方式)

SparkSession spark = SparkSession.builder(0.appName("WordCountCluster").getOrCreate();
JavaRDD<String> Lines = spark.read().textFile ("hdfs://h0:9000/spark.txt").javaRDD();

注:
使用HDFS文件创建RDD对比使用本地文件创建RDD,需要修改的只有两个地方:
1、将SparkSession对象的master(“local”)方法去掉
2、我们针对不是本地文件,修改hadoop hdfs上的真正的存储大数据的文件

操作RDD

Spark支持两种RDD操作:Transformation算子和Action算子。

Transformation操作

transformation操作会针对已有的RDD创建一个新的RDD,transformation具有Lazy特性,即transfromation不会触发Spark程序的执行,他们只是记录来了对RDD多做的操作,不会自发的执行。只有执行一个action,之前的所有的transformation算子才会执行。

常用的transformation介绍:
map:将RDD中的每个元素传入自定义函数,获取一个新的元素,然后用新的元素组成新的RDD。
filter:对RDD中的每个元素进行判断,如果返回true则保留,返回false则剔除。
flatMap:与map类似,是先切分再压平
groupByKey:根据key进行分组,每个key对应一个Iterable。
reduceByKey:对每个key对应的value进行reduce操作。
sortByKey:对每个Key对应的value进行排序操作。
join:对两个包含<key.value>对的 RDD进行join操作,每个keyjoin上的pair,都会传入自定义函数进行处理。
cogroup:同join,但是每个key对应的Iterable都会传入自定义函数进行处理。

action操作

action操作主要对RDD进行最后的操作,比如:遍历,reduce,保存文件等,并可以返回结果给Driver程序。action操作的执行,会产生一个spark job的运行,从而触发这个action之前所有的transformation的执行,这是action的特性。
常用的action算子的介绍:
reduce:将RDD中所有元素进行聚合操作,第一个和第二个元素聚合,值与第三个元素聚合,值与第四个聚合,以此类推。
collect:将RDD中所有元素偶去到本地客户端(一般不建议使用)
count:获取RDD中元素总数
take(n):获取RDD中前n个元素
saceAsTectFile:将RDD元素保存在文件中,对每个元素调用toString方法。
countByKey:对每个key对应的值进行count计数。
foreach:遍历RDD中的每个元素

RDD持久化

作用:当持久化一个 RDD 时,每个节点的其它分区都可以使用 RDD在内存中进行计算,在该数据上的其他 action 操作将直接使用内存中的数据。这样会让以后的 action 操作计算速度加快。

要持久化一个RDD,只要调用cache()或者persist()方法即可,在该RDD第一次被计算出来是,就会直接缓存在每一个节点中,但是cache()或者persist()方法使用是有规则的,必须在transformation或者textFile等创建了一个RDD之后,直接连续调用cache()或persist才可以。
注:如果你下创建一个RDD,然后单独另起一行调用cache()或persist()方法,是没有用的,而且会报错,大量文件会丢失。
如下调用:

val lines = spark。read.texFile(“hdf://”h0:9000/spark.txt).persist()

Spark提供的多种持久化级别,主要是为了在磁盘和内存消耗之间进行取舍。
通用的持久化级别的选择建议:
1、优先使用MEMORY_ONLY,如果可以缓存所有数据的话,那么就是用这种策略,因为纯内存速度最快,而且没有序列化,不需要消耗CPU进行反序列化操作。
2、如果MEMORY_ONLY策略,无法存储所有数据的话,那么使用MEMORY_ONLY_SRE.,将数据进行序列化存储,纯内存操作还是比较快的,只是要消耗CPU进行反序列化。
3、如果需要进行快速的失败恢复,那么就选择后缀为_2的策略,进行数据的备份,这样在失败时,就不需要重新计算了。
4、能不使用DISK相关的策略就不要使用,从磁盘读取数据速度非常慢,有时候从磁盘读取数据还不如重新计算一次。

共享变量

spark提供了两种共享变量:Broadcast Variable(广播变量)和Accmulator(累加变量)。

BroadcastVariable会将使用到的变量,仅仅为每个节点拷贝一份,更大的用处就是优化性能,减少网络传输以及内存消耗。广播变量是只读的。

val factor = 3 
val broadcastVars = sc.broadcast(factor);
val numberList = Array(1,2,3,4,5)
val number = sc.parallelize(numberList).map(num => num* broadcastVars.value)  //广播变量取值broadcastVars.value

Accumulator累加器则可以让多个task共同操作一份变量,主要可以进行累加操作。task只能对Accumulator进行累加操作,不能读取他的值,只有Driver程序可以读取Accumulator的值。

val numberList = Array(1,2,3,4,5)
val numberRDD = sc.parallelize(numberList,1)
val sum  = sc.accumlator(0)numberRDD.foreach{m => sum+=m}

案例代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值