sparkRDD

SparkRDD:
     RDD(弹性分布式数据集)
     RDD是spark提供的核心抽象,在抽象的意义上来说是一种元素集合,包含了数据。他是被分区 的,分为多个分区。每个分区分布在集群中的不同点上,从而让RDD中的数据可以被并行操作。(分布式数据集)。RDD通常通过Hadoop上的文件,即HDFS文件或者Hive表 ,来进行创建,也可以通过应用程序中的集合来创建 
     RDD的数据 默认情况下存储在内存中,但是在内存资源不足时,Spark会自动将RDD数据写入磁盘 (弹性)
     RDD最重要的特性就是,提供了容错性,可以自动从节点失败中恢复过来,如果某个节点上的RDD partition,因节点故障,导致数据丢了,那么RDD会自动通过数据来源重新计算该partition
RDD的定义:
     一个RDD对象,包含以下五个核心属性:
         1.一个分区列表,每个分区里是RDD的一部分数据(或数据块)
         2.一个依赖列表,存储依赖的其他的RDD
         3.一个名为computer的计算函数,用于计算RDD各分区的值
         4.分区器(可选),用于键/值类型的RDD,比如某个RDD是按散列来分区的
         5.计算各分区时优先的位置列表(可选),比如从HDFS上的文件生成RDD时,RDD分区的位置优先选择数据所在的节点,这样可以避免数据移动带来的开销
创建RDD
     进行Spark核心编程时,首先需要进行的就算是创建一个初始的RDD。该RDD中,通常包含了 Spark应用程序的输入源数据。在创建了初始的RDD之后,才可以通过Spark  Core提供的transformation算子,对该RDD进行转换获取其他的RDD
RDD的创建方式:
     1.并行化集合创建RDD
         如果通过并行化集合来创建RDD,需要针对程序中的集合,调用SparkContext的parallelize()方法,Spark会将集合中的数据拷贝到集群上去,形成一个分布式的数据集合,也就是一个RDD
         相当于集合中的一部分数据会到一个节点上,而另一部分数据回到其他节点上,然后就可以用并行的方式来操作这个分布式数据集合
         案例:1 到10 累加求和
             val arr = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
             val rdd = sc.parallelize(arr)
             val sum = rdd.reduce(_ + _)
             调用parallelize()时,有一个重要的参数可以指定,就是要将集合切分成多少个partition。
             Spark会为每一个partition运行一个task来进行处理。
             Spark默认会根据集群的情况来设置partition的数量,但是也可以在调用parallelize()方法时,传入第二个参数,来设置RDD的partition数量。比如parallelize(arr, 10)
     2.使用本地文件和HDFS创建RDD
         Spark是支持使用任何Hadoop支持的存储系统上的文件创建RDD的,比如说HDFS、Cassandra、HBase以及本地文件。通过调用SparkContext的textFile()方法,可以针对本地文件或者HDFS文件创建RDD。
         注意:Spark的textFile()方法支持针对目录,压缩文件以及通配符进行RDD创建。
         Spark默认会为hdfs文件的每一个block创建一个partition,但是也可以通过textFile()的第二个参数手动设置分区数量,只能比block数量多,不能比block数量少 。
         案例:文件字数统计
             val rdd = sc.textFile("data.txt")
             val wordCount = rdd.map(line => line.length).reduce(_ + _)
             注:Spark的textFile()除了可以针对上述几种普通的文件创建RDD之外,
             还有一些特列的方法来创建RDD:
             1》SparkContext.wholeTextFiles()方法,可以针对一个目录中的大量小文件,
             返回组成的pair,作为一个PairRDD,而不是普通的RDD。
             普通的textFile()返回的RDD中,每个元素就是文件中的一行文本。
             2》SparkContext.sequenceFile[K, V]()方法,可以针对SequenceFile创建RDD,
             K和V泛型类型就是SequenceFile的key和value的类型。K和V要求必须是
             Hadoop的序列化类型,比如IntWritable、Text等。
             3》SparkContext.hadoopRDD()方法,对于Hadoop的自定义输入类型,可以创建
             RDD。该方法接收JobConf、InputFormatClass、Key和Value的Class。
             4》SparkContext.objectFile()方法,可以针对之前调用RDD.saveAsObjectFile()
             创建的对象序列化的文件,反序列化文件中的数据,并创建一个RDD。


transformation和action介绍
     transformation操作会针对已有的RDD创建一个新的RDD;
     action则主要是对RDD进行最后的操作,比如遍历、reduce、保存到文件等,并可以返回结果给Driver程序。
     map就是一种transformation操作,它用于将已有RDD的每个元素传入一个自定义的函数,并获取一个新的元素,然后将所有的新元素组成一个新的RDD。
     reduce就是一种action操作,它用于对RDD中的所有元素进行聚合操作,并获取一个最终的结果,然后返回给Driver程序。
     ransformation的特点就是lazy特性。
         lazy特性指的是,如果一个spark应用中只定义了transformation操作,transformation是不会触发Spark程序的执行的,它们只是记录了对RDD所做的操作,但是不会自发的执行。
         只有当执行了一个action操作之后,所有的transformation才会执行。
         Spark通过这种lazy特性来进行底层的Spark应用执行的优化,避免产生过多中间结果。
         action操作执行,会触发一个spark job的运行,从而触发这个action之前所有的transformation的执行,这是action的特性。
         案例:统计文件字数
             1》这里通过textFile()方法,针对外部文件创建了一个RDD lines,但是实际上,程序执行到这里为止,spark.txt文件的数据是不会加载到内存中的。lines,只是代表了一个指向spark.txt文件的引用。
             val lines = sc.textFile("spark.txt")
             2》这里对lines RDD进行了map算子,获取了一个转换后的lineLengths RDD,但是这里连数据都没有,当然也不会做任何操作。lineLengths RDD也只是一个概念上的东西而已。
             val lineLengths = lines.map(line => line.length)
             3》之后,执行了一个action操作,reduce。此时就会触发之前所有transformation操作的执行,Spark会将操作拆分成多个task到多个机器上并行执行,每个task会在本地执行map操作,并且进行本地的reduce聚合。最后会进行一个全局的reduce聚合,然后将结果返回给Driver程序。
             val totalLength = lineLengths.reduce(_ + _)
transformation类型的常用算子介绍
     {map:将RDD中的每个元素传入自定义函数,获取一个新的元素,然后用新的元素组成新的RDD
     filter:对RDD中的每个元素进行判断,如果返回true则保留,返回false则剔除}:父RDD的每个分区都只被子RDD的一个分区使用(窄依赖)
     flatMap:与map类似,但是对每个元素都可以返回一个或多个新元素
     {groupByKey:根据key进行分组,每个key对应 一个iterable
     reduceByKey:对每个key对应的value进行reduce操作
     sortByKey:对每个key对应的value进行操作}:父RDD的分区被子RDD的多个分区使用(宽依赖)
     join:对两个包含对的RDD进行join操作,每个key join上的pair,都会 传入自定义函数进行处理
     cogroup:同join,但是是每个key对应的iterable都会传入自定义函数进行处理
action类型的常用算子
     reduce:将RDD中的所有元素进行聚合操作。第一个和第二个元素聚合,值与第三个元素聚合,值与第四个元素聚合,依此类推
     collect:将RDD中所有的元素获取到本地客户端
     count:获取RDD元素总数
     take(n):获取RDD中的前n个元素
     saveAsTestFile:将RDD元素保存到文件中,对每个元素调用toString方法
     countByKey:对每个key对应的值进行count计数
     foreach:遍历RDD中的每个元素
     collect:从集群中将所有的计算结果获取到本地内存,然后展示
     take:从集群中将一部分的计算结果获取到本地内存,然后展示
补充:
1、map:一次处理一个分区中的一条记录
     mapPartitions:一次处理一个分区中的所有数据
     mapPartitionsWithIndex:一次处理一个分区中的所有数据,并返回分区中的索引,索引从0开始
2、mapValues运算
     可以针对RDD内每一组(key,value)进行运算, 并且产生另外一个RDD。
     例如: 将每一组( key,value) 的value进行平方运算
     kvRDD1.mapValues(x => x*x).collect
3、union
     union方法( 等价于“++”) 是将两个RDD取并集, 取并集的过程中不会把相同元素去掉
     union操作是输入分区与输出分区多对一模式。
4、distinct:distinct方法是将RDD中重复的元素去掉, 只留下唯一的RDD元素。
5、intersection交集运算:intersection方法可以获取两个RDD中相同的数据
6、subtract差集运算
     intRDD1.subtract(intRDD2).collect()
     intRDD1是List(3,1,2,5,5), 扣除intRDD2 List(5,6)重复的部分5, 所以结果是(1,2,3)
7、aggregateByKey
     reduceByKey认为是aggregateByKey的简化版
     aggregateByKey最重要的一点是, 多提供了一个函数, Seq Function
     可以控制如何对每个partition中的数据进行先聚合, 类似于mapreduce中的map-side-combine, 然后才是对所有partition中的数据进行全局聚合
     aggregateByKey, 分为三个参数:
     第一个参数是, 每个key的初始值
     第二个是个函数, Seq Function, 如何进行shuffle map-side的本地聚合
     第三个是个函数, Combiner Function, 如何进行shuffle reduce-side的全局聚合
8、cartesian
     cartesian, 中文名笛卡尔乘积
     比如说两个RDD, 分别有10条数据, 用了cartesian算子以后,两个RDD的每一条数据都会和另外一个RDD的每一条数据执行一次join,最终组成了一个笛卡尔乘积
9、coalesce
     coalesce算子, 功能是将RDD的partition缩减, 将一定量的数据压缩到更少的partition中去。
     建议的使用场景, 配合filter算子使用。使用filter算子过滤掉很多数据以后, 比如30%的数据, 出现了很多partition中的数据不均匀的情况,此时建议使用coalesce算子, 压缩rdd的partition数量, 从而让各个partition中的数据都更加的紧凑。
10、repartition
     repartition算子, 用于任意将rdd的partition增多或者减少。与coalesce不同之处在于, coalesce仅仅能将rdd的partition变少, 但是repartition可以将rdd的partiton变多
     一个很经典的场景, 使用Spark SQL从hive中查询数据时,Spark SQL会根据hive对应的hdfs文件的block数量来决定加载出来的数据rdd中有多少个partition, 这里的partition数量, 是我们根本无法设置的。有时候可能自动设置的partition数量过少, 导致我们后面的算子的运行特别慢;此时就可以在Spark SQL加载hive数据到rdd之后, 立即使用repartition算子,将rdd的partition数量变多。

yarn队列:
     Capacity Scheduler:
         每个组固定享有集群里的一部分资源保证低保,同时如果这个固定的资源空闲,那么可以提供给其他组来抢占,但是一旦这些资源的固定使用者要用,那么立即释放给他使用

你可能感兴趣的:(sparkRDD)