概述
Apache Spark是一个分布式计算框架。
支持的数据存储
- HIVE
- Cassandra
- HBase
- Parquest
- Amazon S3
- MySQL
- HDFS
- Kafaka
- JSON
体系结构
- Driver:解析用户代码,在worker节点上创建多个executor;
- Executor:运行在worker节点上的JVM,用于提供运行任务的硬件资源;
集群管理
支持的调度器有:
- Standalone Scheduler:Spark自己的调度器。当在没有Hadoop安装的集群上运行Spark程序时,这个调度器是一个选择;
- YARN:Hadoop的默认调度器。它对于批处理任务进行了优化。
- Mesos:使用和Linux内核同样的原理创建的,它没有绑定到Hadoop上,YARN对于批处理任务进行了优化,而Mesos比较适合流处理任务;
- Kubernetes:是一个容器的编排框架,可以提供在一个物理集群上运行多个版本的Spark和共享命名空间的能力。
Hadoop和Spark的区别
Hadoop主要由以下组件组成:
- Hive和Pig
- MapReduce
- YARN
- HDFS
HDFS是存储层。
MapReduce是一个编程模型,主要由四个阶段组成:Map、Sort、Shuffle和Reduce。
Hadoop和Spark的一个区别是MR是和数据的格式紧耦合的,而Spark提供了一个RDD的概念,类似一个分布式数据的容器;另一个不同是Spark利用内存,它可以把数据缓存到内存中,来避免磁盘IO,而MR则包含多次磁盘IO。
Spark的执行模式
- Master可以和executor运行在同一个本地机器上;
- 通过提供host和port运行在一台指定的机器上;
Spark核心元素
- Spark SQL
- Spark Streaming
- Machine Learning
- GraphX
- Spark Core
Spark Core
- 定义了基础组件,如:RDD和DataFrame等;
- 定义了操作基础组件的API;
- 定义了共享或分布式变量,如:广播变量和聚集器;
- 定义了所有的基本功能,如:任务管理、内存管理和基础的IO功能等;
Spark SQL
使开发者可以操作结构化,或有语义结构的数据如:Hive tables、MySQL tables、Parquet文件、AVRO文件、JSON文件、CSV文件等。Spark SQL可以用SQL语句来操作数据
Spark Streaming
用于处理实时的数据流。
Spark Machine Learning
Spark MLlib和ML是spark用于机器学习的两个包,它们提供了:
- 内置的机器学习算法:分类、回归、聚类等;
- 提供了一些,如:pipeline、vector创建等的特性
Spark GraphX
用于处理图数据。图包含点和边。边用于定义点的关系。GraphX使用RDD用于计算、创建点和边;GraphFrame是一个外部的包,它使用DataFrame来定义点和边。
基础
RDD
是Spark程序的基本创建单元。一个RDD表现为一个只读的、分布在多台机器上的数据的集合。RDD的全称是Resilient Distributed Datasets:
- Resilient:RDD可以在发生问题时,重新创建自己。每个RDD会记录一些它父RDD和它自己如何创建的信息。
- Distributed:一个RDD可以把它的数据集分布到一组机器上,然后这些机器处理自己负责的部分数据。
- Dataset:就是数据的集合。
Resilient metadata
RDD本身会包含一些metadata,用于帮助spark在发生问题时,重建一个RDD分区。而且在执行操作时,对优化提供支持。metadata提供了如下信息:
- parent RDDS;
- 用于从parent RDDS计算出RDD分区的函数;
- 分区的推荐位置;
- 分区信息;
RDD的三个重要特征
- 依赖(指定如何构建需要的输入)
- 分区(基于分区,可以分割工作进行并行计算)
- 计算函数
使用RDD
创建
RDD可以通过四种方式进行创建:
- Parallelize a collection:使用既有的集合,然后使用Spark把集合分布到集群上,用于并行处理。可以通过parallelize方法进行集合的分布:
val numRDD = spark.sparkContext.parallelize(1 to 100)
- 从外部数据集创建:
val filePath = "/Users/yangxiaochen/temp/a/03/sampleFile.log"
val logRDD = spark.sparkContext.textFile(filePath)
- 基于其它RDD进行创建:
val wholeNumRDD = spark.sparkContext.parallelize(1 to 10)
val evenNumRDD = wholeNumRDD.filter(_ % 2 == 0)
- 从一个DataFrame或DataSet进行创建:
不建议使用,因为DF和DS就是在RDD之上的抽象
val rangeDF = spark.range(1, 5)
val rangeRDD = rangeDF.rdd
转换和动作
转换
转换有两种类型narrow transformation和wide transformation。
Narrow Transformation
在已经分区的数据基础上进行transformation,这样就不会涉及到数据的移动,而且新的RDD和它的父RDD有着同样的分区数。如:map()、flatMap()、filter()、union()、mapPartitions()等
Wide transformation
此种转换涉及到了分区间的数据流动。如:groupByKey()、reduceByKey()、sortby()、join()、distince()、subtract()和intersect()等。因为涉及到了数据流动,所以此类操作比较浪费计算资源。
Action
只有在Action需要在RDD上执行时,在RDD上指定的Transformation才会被执行,Action不会创建一个新的RDD,它用于以下方面:
- 向Driver返回一个最终的结果
- 向外部存储写入最终结果
- 在RDD的每个元素上面执行一些操作
collect
返回RDD的所有元素;
count
返回RDD中元素的数量;