目录
一、相关术语
二、Spark特征
三、Spark整体工作流程
四、Spark运行方式
五、Spark SQL
六、Spark MLlib
七、PySpark
八、Spark Streaming集成Kafka
1. RDD(Resilient Distributed Dataset):弹性分布式数据集,是记录的只读分区集合,是Spark的基本数据结构。RDD代表一个不可变、可分区、里面的元素可并行计算的集合。RDD的依赖关系分为两种:窄依赖(Narrow Dependencies)、宽依赖(Wide Dependencies)。Spark会根据宽依赖窄依赖来划分具体的Stage,依赖可以高效地解决数据容错。
子RDD分区与数据规模无关;
子RDD分区与数据规模有关。
2. DAG(Directed Acyclic Graph):有向无环图,在Spark里每一个操作生成一个RDD,RDD之间连成一条边,最后生成的RDD和他们之间的边组成一个有向无环图。有了计算的DAG图,Spark内核下一步的任务就是根据DAG图将计算划分成任务集,也就是Stage。
3. RDD与DAG的关系:Spark计算的中间结果默认保存在内存中,Spark在划分Stage的时候会充分考虑在分布式计算中,可流水线计算(pipeline)的部分来提高计算效率,而在这个过程中Spark根据RDD之间依赖关系的不同,将DAG划分成不同的Stage(调度阶段)。对于窄依赖
,partition的转换处理在一个Stage中完成计算;对于宽依赖
,由于有Shuffle的存在,只能在parent RDD处理完成后,才能开始接下来的计算,因此宽依赖是划分Stage的依据
。
4. Application:用户编写的Spark应用程序。
5. Job:一个作业包含多个RDD及作用于相应RDD上的各种操作。
6. Task:任务运行在Executor上的工作单元,是Executor中的一个线程。
三者关系:Application由多个Job组成,Job由多个Stage组成,Stage由多个Task组成,Executor进程以多线程的方式运行Task。
7. Action:该操作将触发基于RDD依赖关系的计算。
8. Transformation:该转换操作具有懒惰执行的特性,它只指定新的RDD和其父RDD的依赖关系,只有当Action操作触发到该依赖的时候,它才被计算。
9. PairRDD:指数据为Tuple2数据类型的RDD,其每个数据的第一个元素被当做key,第二个元素被当做value。
10. 持久化操作:声明对一个RDD进行cache后,该RDD不会被立即缓存,而是等到它第一次因为某个Action操作触发后被计算出来时才进行缓存。可以使用persist明确指定存储级别,常用的存储级别是MEMORY_ONLY和MEMORY_AND_DISK。
11. 共享变量:当Spark集群在许多节点上运行一个函数时,默认情况下会把这个函数涉及到的对象在每个节点生成一个副本。但是,有时候需要在不同节点或者节点和Driver之间共享变量。Spark提供两种类型的共享变量:广播变量、累加器。
12. 广播变量:
高效性:不同于MapReduce将中间计算结果放入磁盘中,Spark采用内存存储中间计算结果,减少了迭代运算的磁盘IO,并通过并行计算DAG图的优化,减少了不同任务之间的依赖,降低了延迟等待时间。
易用性:Spark提供了超过80种不同的算子,如map,reduce,filter,groupByKey,sortByKey,foreach等;Spark task以线程的方式维护,对于小数据集读取能够达到亚秒级的延迟。
通用性:Spark可以用于批处理、交互式查询(Spark SQL)、实时流处理(Spark Streaming)、机器学习(Spark MLlib)和图计算(GraphX)。
兼容性:Spark能够跟很多开源工程兼容使用。如Spark可以使用Hadoop的YARN和Apache Mesos作为它的资源管理和调度器,并且Spark可以读取多种数据源,如HDFS、HBase、MySQL等。
Spark运行架构特点:
spark本身是用Scala编写的,spark1.4.0 起支持R语言和Python3编程。
Spark SQL 是从shark发展而来。
Spark SQL在Hive兼容层面仅依赖HQL parser、Hive Metastore和Hive SerDe(后两者用于兼容Hive存储格式)。
默认的是parquet,可以通过spark.sql.sources.default,修改默认配置。
Spark SQL可支持多种数据格式:json, parquet, jdbc, orc, libsvm, csv, text;
其中hive表使用:
版本 | 缓存 | 释放缓存 |
spark2.+ | spark.catalog.cacheTable("tableName")缓存表 | spark.catalog.uncacheTable("tableName")清空缓存 |
spark1.+ | sqlContext.cacheTable("tableName")缓存 | sqlContext.uncacheTable("tableName") 清空缓存 |
Spark SQL仅仅会缓存必要的列,并且自动调整压缩算法来减少内存和GC压力。
属性 | 默认值 | 描述 |
spark.sql.inMemoryColumnarStorage.compressed | true | Spark SQL 将会基于统计信息自动地为每一列选择一种压缩编码方式。 |
spark.sql.inMemoryColumnarStorage.batchSize | 10000 | 缓存批处理大小。缓存数据时, 较大的批处理大小可以提高内存利用率和压缩率,但同时也会带来 OOM(Out Of Memory)的风险。 |
spark.sql.files.maxPartitionBytes | 128 MB | 读取文件时单个分区可容纳的最大字节数(不过不推荐手动修改,可能在后续版本自动的自适应修改) |
spark.sql.files.openCostInBytes | 4M | 打开文件的估算成本, 按照同一时间能够扫描的字节数来测量。当往一个分区写入多个文件的时候会使用。高估更好, 这样的话小文件分区将比大文件分区更快 (先被调度)。 |
属性 | 默认值 | 描述 |
spark.sql.broadcastTimeout | 300 | 广播等待超时时间,单位秒 |
spark.sql.autoBroadcastJoinThreshold | 10M | 用于配置一个表在执行 join 操作时能够广播给所有 worker 节点的最大字节大小。通过将这个值设置为 -1 可以禁用广播。注意,当前数据统计仅支持已经运行了 ANALYZE TABLE |
在任务超多,广播变量在跨stage使用数据的时候才能凸显其真正作用。
属性 | 默认值 | 描述 |
spark.sql.shuffle.partitions | 200 | 用于配置 join 或aggregate混洗(shuffle)数据时使用的分区数。 |
spark.default.parallelism | 对于分布式shuffle操作像reduceByKey和join,父RDD中分区的最大数目。 对于无父RDD的并行化等操作,它取决于群集管理器: -本地模式:本地计算机上的核心数 -Mesos fine grained mode:8 -其他:所有执行节点上的核心总数或2,以较大者为准 |
分布式shuffle操作的分区数 |
在实际测试中,spark.sql.shuffle.partitions是对sparks SQL的专用设置;spark.default.parallelism只有在处理RDD时才会起作用,对Spark SQL的无效。
属性 | 默认值 | 描述 |
spark.sql.files.maxPartitionBytes | 134217728 (128 MB) | 打包传入一个分区的最大字节,读取文件的时候一个分区接受多少数据; |
spark.sql.files.openCostInBytes | 4194304 (4 MB) | 文件打开是有开销的,Spark 用相同时间能扫描的数据的字节数来衡量打开文件的开销。当将多个文件写入同一个分区的时候该参数有用。该参数设置较大,有小文件的分区会比大文件分区处理速度更快(优先调度)。 |
spark.sql.files.maxPartitionBytes该值的调整要结合你想要的并发度及内存的大小来进行;spark.sql.files.openCostInBytes说直白一些这个参数就是合并小文件的阈值,小于这个阈值的文件将会合并。
文件格式建议使用parquet或者orc;parquet已经可以达到较大性能。
注:Spark官方推荐使用spark.ml,并预期于3.0版本移除spark.mllib
。使用 ML Pipeline API可以很方便的把数据处理,特征转换,正则化,以及多个机器学习算法联合起来,构建一个单一完整的机器学习流水线。
离散型数据 | 连续型数据 | |
监督学习 | 分类、逻辑回归、SVM、决策树、随机森林、GBT、朴素贝叶斯、多层感知机(Multi-Layer Perceptron)、One-Vs-Rest | 回归、线性回归、决策树、随机森林、GBT、AFT生存回归、保序回归(Isotonic Regression) |
无监督学校 | 聚类、K-Means、高斯混合(Gaussian Mixture)、LDA、幂迭代聚类(Power iteration)、二分K均值(Bisecting K-Means) | 降维、矩阵分解(Matrix Factorization)、主成分分析(PCA)、基于奇异值分解(SVD)、最小二乘法(ALS)、加权最小二乘法(WLS) |
存储在单机上,拥有整型、从0开始的索引值以及浮点型的元素值。
DenseVector
)使用一个双精度浮点型数组来表示其中每一维元素,而稀疏向量(SparseVector
)则是基于一个整型索引数组和一个双精度浮点型的值数组。一种带有标签(Label/Response)的本地向量,它可以是稠密或者是稀疏的。
1
,负样本的标签为0
;而多分类标签则是一个以0开始的索引序列,如:0, 1, 2 ...存储在单机上,具有整型的行、列索引值和双精度浮点型的元素值。其中稠密矩阵将所有元素的值存储在一个列优先(Column-major)的双精度型数组中,而稀疏矩阵则将非零元素以列优先的CSC(Compressed Sparse Column)模式进行存储。
由长整型的行列索引值和双精度浮点型的元素值组成,可以分布式地存储在一个或多个RDD上。
1)行矩阵(Row Matrix)是最基础的分布式矩阵类型。每行是一个本地向量,行索引无实际意义(即无法直接使用)。数据存储在一个由行组成的RDD中,其中每一行都使用一个本地向量来进行存储。由于行是通过本地向量来实现的,故列数(即行的维度)被限制在普通整型。在实际应用中,由于单机处理本地向量的存储和通信代价,行维度更是需要被控制在一个更小的范围之内。
2)索引行矩阵(Index Row Matrix):与行矩阵相似,但它的每一行都带有一个有意义的行索引值,这个索引值可以被用来识别不同行,其数据存储在一个由IndexRow组成的RDD里,即每一行都是一个带长整型索引的本地向量。
3)坐标矩阵(Coordinate Matrix):一个基于矩阵项构成的RDD的分布式矩阵每一个矩阵项(MatrixEntry
)都是一个三元组(i: Long, j: Long, value: Double),其中i
是行索引,j
是列索引,value
是该位置的值。坐标矩阵一般在矩阵的两个维度都很大,且矩阵非常稀疏的时候使用。
4)分块矩阵(Block Matrix):分块矩阵将矩阵分成一系列矩阵块,底层由矩阵块构成的RDD来进行数据存储,每一个矩阵块都是一个元组((Int, Int), Matrix)
,其中(Int, Int)
是块的索引,Matrix
是在对应位置的子矩阵(sub-matrix),其尺寸由rowsPerBlock
和colsPerBlock
决定,默认值均为1024。
validate()
来确认分块矩阵是否创建成功。分块矩阵可由索引行矩阵(IndexedRowMatrix
)或坐标矩阵(CoordinateMatrix
)调用toBlockMatrix(rowsPerBlock, colsPerBlock)
方法来进行转换,该方法将矩阵划分成尺寸默认为1024x1024的分块,可以在调用该方法时传入参数来调整分块的尺寸。