Spark大数据分析入门笔记

目录

一、相关术语

二、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,依赖可以高效地解决数据容错

  1. 窄依赖:每个父RDD的一个Partition最多被子RDD的一个Partition所使用(1:1 或 n:1)。例如map、filter、union等操作都会产生窄依赖。子RDD分区与数据规模无关;
  2. 宽依赖:一个父RDD的Partition会被多个子RDD的Partition所使用(1:m 或 n:m),例如groupByKey、reduceByKey、sortByKey等操作都会产生宽依赖。子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提供两种类型的共享变量:广播变量、累加器。

  1. 广播变量:不可变变量,实现在不同节点不同任务之间共享数据;广播变量在每个节点上缓存一个只读的变量,而不是为每个task生成一个副本,可以减少数据的传输。
  2. 累加器:主要用于不同节点和Driver之间共享变量,只能实现计数或者累加功能;累加器的值只有在Driver上是可读的,在节点上只能执行add操作。

12. 广播变量:

  • 广播变量是一个只读变量,通过它我们可以将一些共享数据集或者大变量缓存在Spark集群中的各个机器上而不用每个task都需要copy一个副本,后续计算可以重复使用,减少了数据传输时网络带宽的使用,提高效率。相比于Hadoop的分布式缓存,广播的内容可以跨作业共享。
  • 广播变量要求广播的数据不可变、不能太大但也不能太小(一般几十M以上)、可被序列化和反序列化、并且必须在driver端声明广播变量,适用于广播多个stage公用的数据,存储级别目前是MEMORY_AND_DISK。
  • 广播变量存储目前基于Spark实现的BlockManager分布式存储系统,Spark中的shuffle数据、加载HDFS数据时切分过来的block块都存储在BlockManager中。

二、Spark特征

高效性:不同于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运行架构特点

  1. 每个Application均有专属的Executor进程,并且该进程在Application运行期间一直驻留;
  2. Spark运行过程与资源管理器无关,只要能够获取Executor进程并保持通信即可;
  3. Task采用了数据本地性和推测执行等优化机制。

三、Spark整体工作流程

  1. 构建Spark Application运行环境;
  2. SparkContext向资源管理器注册;
  3. SparkContext向资源管理器申请运行Executor;
  4. 资源管理器分配Executor;
  5. 资源管理器启动Executor;
  6. Executor发送心跳至资源管理器;
  7. SparkContext构建成DAG图;
  8. 将DAG图分解成Stage(TaskSet);
  9. 把Stage(TaskSet)发送给TaskScheduler;
  10. Executor向SparkContext申请Task;
  11. TaskScheduler将Task发送给Executor运行;同时SparkContext将应用程序代码发放给Executor;
  12. Task在Executor上运行,运行完毕释放所有资源。

Spark大数据分析入门笔记_第1张图片

四、Spark运行方式

spark本身是用Scala编写的,spark1.4.0 起支持R语言和Python3编程。

  1. 通过spark-shell进入Spark交互式环境,使用Scala语言;
  2. 通过spark-submit提交Spark应用程序进行批处理;该方法可以提交Scala或Java语言编写的代码编译后生成的jar包,也可以直接提交Python脚本。
  3. 通过pyspark进入pyspark交互式环境,使用Python语言;该方式可以指定jupyter或者ipython为交互环境。
  4. 通过zepplin notebook交互式执行;zepplin在jupyter notebook里。
  5. 安装Apache Toree-Scala内核,可以在jupyter 中运行spark-shell。使用spark-shell运行时,可以添加两个常用的两个参数:master指定使用何种分布类型;jars指定依赖的jar包。

五、Spark SQL

Spark SQL 是从shark发展而来。

1、Spark SQL兼容性

Spark SQL在Hive兼容层面仅依赖HQL parserHive MetastoreHive SerDe后两者用于兼容Hive存储格式)。

  • 从HQL被解析成抽象语法树(AST)起,就全部由Spark SQL接管。
  • 执行计划生成和优化都由Catalyst负责,借助Scala的模式匹配等函数式语言特性,利用Catalyst开发执行计划优化策略比Hive要简洁得多。

2、Spark SQL编码方式tips

  1. 直接通过Spark编码:需提前声明构建SQLContext或者是SparkSession(Spark2之后建议使用);
  2. spark-sql(shell)脚本编码:启动前可以通过bin/spark-sql –help 查看配置参数,调整部署模式资源等;
  3. Thriftserver编码:基于HiveServer2实现的一个Thrift服务,旨在无缝兼容HiveServer2。部署好Spark Thrift Server后,可以直接使用hive的beeline访问Spark Thrift Server,执行相关语句。

3、Spark SQL数据格式

默认的是parquet,可以通过spark.sql.sources.default,修改默认配置。

Spark SQL可支持多种数据格式:json, parquet, jdbc, orc, libsvm, csv, text;

其中hive表使用:

  • spark 1.6及以前的版本需要hivecontext;
  • Spark2开始只需要创建sparksession增加enableHiveSupport()即可。

4、Spark SQL性能优化

(1)在内存中缓存数据,Spark缓存注册表的方法

版本 缓存 释放缓存
spark2.+ spark.catalog.cacheTable("tableName")缓存表 spark.catalog.uncacheTable("tableName")清空缓存
spark1.+ sqlContext.cacheTable("tableName")缓存 sqlContext.uncacheTable("tableName") 清空缓存

Spark SQL仅仅会缓存必要的列,并且自动调整压缩算法来减少内存和GC压力。

(2)性能优化相关参数

属性 默认值 描述
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 打开文件的估算成本, 按照同一时间能够扫描的字节数来测量。当往一个分区写入多个文件的时候会使用。高估更好, 这样的话小文件分区将比大文件分区更快 (先被调度)。

(3)在进行表连接的时候,将小表广播可以提高性能,spark2.+中可以调整参数

属性 默认值 描述
spark.sql.broadcastTimeout 300 广播等待超时时间,单位秒
spark.sql.autoBroadcastJoinThreshold 10M 用于配置一个表在执行 join 操作时能够广播给所有 worker 节点的最大字节大小。通过将这个值设置为 -1 可以禁用广播。注意,当前数据统计仅支持已经运行了 ANALYZE TABLE COMPUTE STATISTICS noscan 命令的 Hive Metastore 表。

在任务超多,广播变量在跨stage使用数据的时候才能凸显其真正作用。

(4)分区数据的调控,spark任务并行度参数设置

属性 默认值 描述
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的无效。

(5)文件与分区

属性 默认值 描述
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 MLlib

1、MLlib是Spark的机器学习库

  1. 算法工具:常用的学习算法,如分类、回归、聚类和协同过滤;
  2. 特征化公交:特征提取、转化、降维和选择公交;
  3. 管道(Pipeline):用于构建、评估和调整机器学习管道的工具;
  4. 持久性:保存和加载算法,模型和管道;
  5. 实用工具:线性代数,统计,数据处理等工具。

2、Spark MLlib包

  1. spark.mllib包含基于RDD的原始算法API。
  2. spark.ml则提供了基于DataFrames 高层次的API,可以用来构建机器学习工作流(PipeLine)。ML Pipeline 弥补了原始 MLlib 库的不足,向用户提供了一个基于 DataFrame 的机器学习工作流式 API 套件。

注:Spark官方推荐使用spark.ml,并预期于3.0版本移除spark.mllib使用 ML Pipeline API可以很方便的把数据处理,特征转换,正则化,以及多个机器学习算法联合起来,构建一个单一完整的机器学习流水线。

3、目前MLlib支持的主要的机器学习算法

  离散型数据 连续型数据
监督学习 分类、逻辑回归、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)

4、MLlib基本数据类型

(1)本地向量(Local Vector)

存储在单机上,拥有整型、从0开始的索引值以及浮点型的元素值。

  • 其中稠密向量DenseVector)使用一个双精度浮点型数组来表示其中每一维元素,而稀疏向量SparseVector)则是基于一个整型索引数组和一个双精度浮点型的值数组。
  • 以向量(1.0, 0.0, 3.0)为例:稠密向量表达形式为[1.0, 0.0, 3.0];稀疏向量形式为(3, [0, 2], [1.0, 3.0]),其中3是向量长度,[0, 2]是向量中非0维度的索引值,[1.0, 3.0]是按索引排列的数组元素值。

(2)标注点(Labeled Point)

一种带有标签(Label/Response)的本地向量,它可以是稠密或者是稀疏的。

  • 标注点仅在监督学习算法中使用,由于标签是用双精度浮点型来存储的,故标注点类型在回归(Regression)和分类(Classification)问题上均可使用。
  • 以二分类为例,正样本的标签为1,负样本的标签为0;而多分类标签则是一个以0开始的索引序列,如:0, 1, 2 ...

(3)本地矩阵(Local Matrix)

存储在单机上,具有整型的行、列索引值和双精度浮点型的元素值。其中稠密矩阵将所有元素的值存储在一个列优先(Column-major)的双精度型数组中,而稀疏矩阵则将非零元素以列优先的CSC(Compressed Sparse Column)模式进行存储。

(4)分布式矩阵(Distributed Matrix)

由长整型的行列索引值和双精度浮点型的元素值组成,可以分布式地存储在一个或多个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),其尺寸由rowsPerBlockcolsPerBlock决定,默认值均为1024。

  • 分块矩阵之间可以进行加法操作和乘法操作,并使用方法validate()来确认分块矩阵是否创建成功。分块矩阵可由索引行矩阵IndexedRowMatrix)或坐标矩阵CoordinateMatrix)调用toBlockMatrix(rowsPerBlock, colsPerBlock)方法来进行转换,该方法将矩阵划分成尺寸默认为1024x1024的分块,可以在调用该方法时传入参数来调整分块的尺寸
  • 分块矩阵用于生成分布式矩阵的底层RDD必须是已经确定(Deterministic)的,因为矩阵的尺寸将被存储下来,所以使用未确定的RDD将会导致错误。而且,不同类型的分布式矩阵之间的转换需要进行一个全局的shuffle操作,非常耗费资源。所以,根据数据本身的性质和应用需求来选取恰当的分布式矩阵存储类型是非常重要的。

5、 机器学习工作流(ML Pipelines)—— spark.ml包

 

七、PySpark

 

八、Spark Streaming集成Kafka

你可能感兴趣的:(机器学习,大数据)