Spark2.3.1 RDD Programming Guide

Spark应用:driver program运行用户main函数并在executors集群执行并行操作

1 Spark提供两种抽象:RDD和shared variables

2 创建RDD的两种方式:在驱动器程序parallelize集合;从外部存储系统引入数据集

    1) SparkContext.parallelize

        可以使用第二个参数传递分区数量,即并行度,sc.parallelize(data, numSlices)

    2) 外部存储系统包括本地文件系统,HDFS,Cassandra,HBase,Amazon S3,并支持文本文件,SequenceFile,和其他的Hadoop InputFormat

        > textFile返回文件的每一line作为一条记录

        > 文件系统的路径要可被所有工作节点访问

        > textFile方法支持路径,压缩文件,wildcards(通配符)

textFile("/my/directory")/textFile("/my/directory/*.txt")/textFile("/my/directory/*.gz").

        > textFile的第二个参数也是分区数量,并行分区数量不能少于文件块的数量(HDFS)

    3)除了textFile方法,Scala API还提供了

        > SparkContext.wholeTextFiles,读取一个文件路径,返回(filename, content)pair RDD

        > SparkContext.sequenceFile[K, V]读取SequenceFile

      > 其他HadoopInputFormats,使用SparkContext.hadoopRDD,使用SparkContext.newAPIHadoopRDD读取new MR API(org.apache.hadoop.mapreduce)

        > RDD.saveAsObjectFile和SparkContext.objectFile支持序列化Java对象的方式保存RDD,不过没有Avro有效率

3 RDD Operations: Transformations and Actions

    1) 转化操作都是惰性求值的

    2) textFile也是惰性的,val lines = sc.textFile(file),lines只是对文件的引用,实际action操作才会进行计算

Spark的函数传递

5 Spark Cluster使用闭包

        > 统计信息时不使用driver自定义外部变量,使用Accumulator累加器,因为自定义外部变量虽然可能在本地有效,但在集群中因为在把driver变量的值复制给各个executor之后,driver中的外部变量对executor不可见,所以在executor中所做的修改并不会应用到driver的变量上,最终driver上的变量还是原来的值,并没有被executor改变

var counter = 0
var rdd = sc.parallelize(data)

// Wrong: Don't do this!!
rdd.foreach(x => counter += x)

println("Counter value: " + counter)

        > 变量和方法的作用范围和生命周期,考虑本地模式还是集群模式,考虑行动操作还是转化操作

6 输出RDD元素

        > 对于单机模式,可以使用rdd.foreach(println)/rdd.map(println),但在Cluster中,这样调用会把输出打印到各个executor的stdout标准输出上,而不是driver的stdout上,所以driver不会有输出

          > 如果需要把cluster的RDD的所有内容输出到driver上,使用collect(),collect()会把RDD所有内容返回给driver内存,rdd.collect().foreach(println),但RDD太大时导致driver内存不足,可使用take()取部分输出,rdd.take(100).foreach(println)

7 Pair RDD

        > Scala中使用Tuple2对象表示[K ,V]

        > 使用自定义对象作为Key时,要实现hashCode()和equals()方法

8 常用transformations和actions

9 Shuffle Operations 混洗操作

10 RDD持久化缓存

        > 持久化RDD,每个节点都把自己计算的分区结果保存在内存中,在之后的操作中可以复用,这一般可以提升10倍的计算速度

        > 如果RDD中的一个分区丢失,则自动重算这个分区

        > StorageLevel,LRU算法自动替换移除,如果需要主动移除,可以调用rdd.unpersist()

        

11 如何选择StorageLevel?

    1) 首选MEMORY_ONLY,这样CPU效率最高,如果合适就使用这种

    2) 次选MEMORY_ONLY_SER,使用序列化对象节省空间,CPU效率也高

    3) 最好不要写到磁盘DISK,数据量很大时可能读取DISK内容的时间和重算的时间还差不多

    4) 如果需要快速失败恢复,使用replicated storage levels,如MEMORY_ONLY_2,在两个不同节点分别保存同一分区

        > 容错机制可以通过自动重算实现,也可以通过保存副本实现

12 共享变量

    1) Spark把函数传递executors执行时,把函数使用到的变量也拷贝到各个executor,在executor上进行的更新不会传回给driver程序,所以Spark提供共享变量 broadcast和accumulator可以解决这种问题


猜你喜欢

转载自blog.csdn.net/weixin_42129080/article/details/80957334
今日推荐