Spark基础

    科技2022-07-10  117

    spark和RDD

    什么是spark

    是大规模数据处理的统一分析引擎,通用内存并行计算框架。

    spark的组成

    SparkCore :实现spark的基本功能,包含任务调度、内存管理等模块。将分布式数据抽象为弹性分布式数据集(RDD),并为运行在其上的上层组件提供API。RDD表示分布在多个计算节点上可以并行操作的元素集合。 SparkSQL :Spark Sql 是Spark来操作结构化数据的程序包,可以让我使用SQL语句的方式来查询数据,Spark支持 多种数据源,包含Hive表,parquest以及JSON等内容。 SparkStreaming : 是Spark提供的实时数据进行流式计算的组件。 MLlib :提供常用机器学习算法的实现库。

    一、RDD:spark中的数据抽象。

    RDD概念:叫做弹性分布式数据集,代表一个不可变、可分区、里面的元素可并行计算的集合。 RDD其实就是分布式的元素集合,每个RDD被分为多个分区,这些分区运行在集群中的不同节点上。在spark中,对数据的操作不外乎创建RDD、转换RDD、以及调用RDD操作进行求值,在这一切背后,Spark会自动将RDD的数据分发到集群上,并将操作并行化执行。

    1.1 RDD的属性

    (1)一组分片(Partition),即数据集的基本组成单位。对于RDD来说,每个分片都会被一个计算任务处理,并决定并行计算的粒度。用户可以在创建RDD时指定RDD的分片个数,如果没有指定,那么就会采用默认值。默认值就是程序所分配到的CPU Core的数目。 (2)一个计算每个分区的函数。Spark中RDD的计算是以分片为单位的,每个RDD都会实现compute函数以达到这个目的。compute函数会对迭代器进行复合,不需要保存每次计算的结果。 (3)RDD之间的依赖关系。RDD的每次转换都会生成一个新的RDD,所以RDD之间就会形成类似于流水线一样的前后依赖关系。在部分分区数据丢失时,Spark可以通过这个依赖关系重新计算丢失的分区数据,而不是对RDD的所有分区进行重新计算。 (4)一个Partitioner,即RDD的分片函数。当前Spark中实现了两种类型的分片函数,一个是基于哈希的HashPartitioner,另外一个是基于范围的RangePartitioner。只有对于于key-value的RDD,才会有Partitioner,非key-value的RDD的Parititioner的值是None。Partitioner函数不但决定了RDD本身的分片数量,也决定了parent RDD Shuffle输出时的分片数量。 (5)一个列表,存储存取每个Partition的优先位置(preferred location)。对于一个HDFS文件来说,这个列表保存的就是每个Partition所在的块的位置。按照“移动数据不如移动计算”的理念,Spark在进行任务调度的时候,会尽可能地将计算任务分配到其所要处理数据块的存储位置。 RDD的特点:分区、只读、依赖、缓存

    1.2 RDD的创建方式

    通过SparkContext来创建和操作RDD。 三种: 1、从集合中创建RDD;使用parallelize 2、从外部存储创建RDD;读取文件、数据库等 3、从其他RDD创建。从其他RDD转换

    1.3RDD编程

    Spark支持两个类型(算子)操作:Transformation和Action 1、Transformation:将一个已有的RDD生成另外一个RDD,Transformation算子的代码不会真正被执行 2、Action:对数据集进行实际计算,RDD在进行Action操作时重新进行计算,如果在多个行动操作中重用一个RDD,可以使用persist()把RDD缓存下来。 转换操作返回的是RDD,行动操作返回的是其他数据类型。 许多转换操作都是针对各个元素的,转换操作每次都只会操作RDD中的一个元素。 每次调用一个新的行动操作时,整个RDD都会从头开始计算,为避免这种低效的行为,可以将中间结果持久化,使用persist。 (我们不应该把RDD看做存放着特定数据的数据集,而是把RDD当作我们通过转换操作构建出来的、记录如何计算数据的指令列表)

    1.4 RDD的宽窄依赖

    宽依赖:指的是多个子RDD的Partition会依赖同一个父RDD的Partition,关系是一对多,父RDD的一个分区的数据去到子RDD的不同分区里面,会有shuffle的产生 窄依赖:指的是每一个父RDD的Partition最多被子RDD的一个partition使用,是一对一的,也就是父RDD的一个分区去到了子RDD的一个分区中,这个过程没有shuffle产生 区分的标准:就是看父RDD的一个分区的数据的流向,要是流向一个partition的话就是窄依赖,否则就是宽依赖

    1.5 划分stage

    Spark任务会根据RDD之间的依赖关系,形成一个DAG有向无环图,DAG会提交给DAGScheduler,DAGScheduler会把DAG划分相互依赖的多个stage,划分依据就是宽窄依赖,遇到宽依赖就划分stage,每个stage包含一个或多个task,然后将这些task以taskSet的形式提交给TaskScheduler运行,stage是由一组并行的task组成

    1、spark程序中可以因为不同的action触发众多的job,一个程序中可以有很多的job,每一个job是由一个或者多个stage构成的,后面的stage依赖于前面的stage,也就是说只有前面依赖的stage计算完毕后,后面的stage才会运行;2、stage 的划分标准就是宽依赖:何时产生宽依赖就会产生一个新的stage,例如reduceByKey,groupByKey,join的算子,会导致宽依赖的产生;3、切割规则:从后往前,遇到宽依赖就切割stage;4、stage的task的并行度是由stage的最后一个RDD的分区数来决定的,一般来说,一个partition对应一个task,但最后reduce的时候可以手动改变reduce的个数,也就是改变最后一个RDD的分区数,也就改变了并行度。例如:reduceByKey(+,3)

    RDD概念 Spark学习之路 (三)Spark之RDD

    Processed: 0.011, SQL: 8