概念理解
Spark和Hadoop的比较
Spark 提供了 Sparkcore RDD 、 Spark SQL 、 Spark Streaming 、 Spark MLlib 、 Spark、GraphX等技术组件,可以一站式地完成大数据领域的离线批处理、交互式查询、流式计算、机器学习、图计算等常见的任务。这就是 spark 一站式开发的特点
MR
Spark
归根结底最重要的区别还是在于 下图为 MapReduce 执行任务流程(MR基于磁盘,Spark基于内存)
多种编程语言的支持: Scala,Java,Python,R,SQL 。
Local
Standalone
Yarn
Mesos
分区的原因
RDD的理解
对于Spark Shuffle阶段的理解
Spark Shuffle阶段共分为Shuffle Write阶段和Shuffle Read阶段,其中在Shuffle Write阶段中,Shuffle Map Task 对数据进行处理并产生中间数据
然后再根据数据分区方式对中间数据进行分区
最终Shuffle Read阶段中的Shuffle Read Task会拉取Shuffle Write阶段中产生的并已经分好区的中间数据
Spark包含两种数据分区方式:HashPartitioner(哈希分区)和RangePartitioner(范围分区)
HashPartitioner分区
partitionId = Key.hashCode % numPartitions
RangePartitioner分区
spark本身并没有提供分布式文件系统,因此spark的分析大多依赖于Hadoop的分布式文件系统HDFS
HDFS-Block
Spark-Partition
BLock和Partition的联系
Block和Partition的区别
Block | Partition | |
---|---|---|
位置 | 存储空间 | 计算空间 |
大小 | 固定 | 不固定 |
数据冗余 | 有冗余的、不会轻易丢失 | 没有冗余设计、丢失之后重新计算得到 |
RDD(Resilient Distributed Dataset) 弹性分布式数据集,Spark计算流程中的一个算子,类似于Storm中的Bolt,对数据进行计算,得到临时结果(partition)
利用内存加快数据加载,在其它的In-Memory类数据库或Cache类系统中也有实现。Spark的主要区别在于它采用血统(Lineage)来时实现分布式运算环境下的数据容错性(节点失效、数据丢失)问题
RDD 的最重要的特性之一就是血缘关系(Lineage ),它描述了一个 RDD 是如何从父 RDD 计算得来的。如果某个 RDD 丢失了,则可以根据血缘关系,从父 RDD 计算得来
当这个RDD的部分分区数据丢失时,它可以通过Lineage找到丢失的父RDD的分区进行局部计算来恢复丢失的数据,这样可以节省资源提高运行效率
系统架构图一:
系统架构图二:
作用
在Standalone模式下
在Yarn模式下
Spark代码流程
创建SparkConf对象
可以设置Application name。
可以设置运行模式及资源需求。
创建SparkContext对象
基于Spark的上下文创建一个RDD,对RDD进行处理。
应用程序中要有Action类算子来触发Transformation类算子执行。
关闭Spark上下文对象SparkContext。
创建SparkConf对象
val sparkConf: SparkConf = new SparkConf().setMaster("local").setAppName("WordCount")
创建SparkContext对象
val sparkContext: SparkContext = new SparkContext(sparkConf)
基于Spark的上下文创建一个RDD,对RDD进行处理。
val value: RDD[(String,Int)] = sparkContext.textFile("src/main/resources/user.log")
应用程序中要有Action类算子来触发Transformation类算子执行。
println(lines.count())
lines.foreach(ele => println("foreach:" + ele))
lines.take(5).foreach(ele => println("take:" + ele))
println(lines.first())
lines.collect().foreach(ele => println("collect:" + ele))
关闭Spark上下文对象SparkContext。
sparkContext.stop()
什么是算子?
可以理解成spark RDD的方法,这些方法作用于RDD的每一个partition。因为spark的RDD是一个 lazy的计算过程,只有得到特定触发才会进行计算,否则不会产生任何结果
Spark 记录了RDD之间的生成和依赖关系,但是只有当F进行行动操作时,Spark才会根据RDD的依赖关系生成DAG,并从起点开始真正的计算,如下图的A、B、C、D分别是一个个RDD
默认将RDD的数据持久化到内存中,cache是 懒执行
rdd.cache().count() 返回的不是持久化的RDD,而是一个数值
/**
* 第一次并不会使用到缓存数据,因为是懒执行所以等到第一次Action才会开始缓存数据
* 第二次用到的就是缓存数据
*/
object Hello04Cache {
def main(args: Array[String]): Unit = {
//1.配置并创建对象
val sparkContext = new SparkContext((new SparkConf().setMaster("local").setAppName("Hello04Cache" + System.currentTimeMillis())))
//2.开始读取数据
var lines: RDD[String] = sparkContext.textFile("src/main/resources/NASA_access_log_Aug95")
//3.开始进行缓存
lines = lines.cache()
//4.开始进行计算
val startTime = System.currentTimeMillis
val count = lines.count
val endTime = System.currentTimeMillis
System.out.println("第一次共" + count + "条数据," + "计算时间=" + (endTime - startTime))
val cacheStartTime = System.currentTimeMillis
val cacheResult = lines.count
val cacheEndTime = System.currentTimeMillis
System.out.println("第二次共" + cacheResult + "条数据," + "计算时间=" + (cacheEndTime - cacheStartTime))
//关闭sparkContext
sparkContext.stop()
}
}
特点:
持久化级别
代码实现
object Hello05Persist {
def main(args: Array[String]): Unit = {
//1.配置并创建对象
val sparkContext = new SparkContext((new SparkConf().setMaster("local").setAppName("Hello05Persist" + System.currentTimeMillis())))
//2.开始读取数据
var lines: RDD[String] = sparkContext.textFile("src/main/resources/NASA_access_log_Aug95")
//3.开始进行缓存
lines = lines.persist(StorageLevel.DISK_ONLY)
//4.开始进行计算
val startTime = System.currentTimeMillis
val count = lines.count
val endTime = System.currentTimeMillis
System.out.println("第一次共" + count + "条数据," + "计算时间=" + (endTime - startTime))
val cacheStartTime = System.currentTimeMillis
val cacheResult = lines.count
val cacheEndTime = System.currentTimeMillis
System.out.println("第二次共" + cacheResult + "条数据," + "计算时间=" + (cacheEndTime - cacheStartTime))
//关闭sparkContext
sparkContext.stop()
}
}
特点
执行原理
使用Checkpoint时常用的优化手段
代码实现
def main(args: Array[String]): Unit = {
val sparkConf = new
SparkConf().setMaster("local").setAppName("SparkCheckPoint" + System.currentTimeMillis())
val sparkContext = new SparkContext(sparkConf)
sparkContext.setCheckpointDir("./checkpoint")
val lines: RDD[String] =
sparkContext.textFile("src/main/resources/NASA_access_log_Aug95")
val words: RDD[String] = lines.flatMap(_.split(" "))
println("words" + words.getNumPartitions)
words.checkpoint
words.count
sparkContext.stop
}
搭建之前确认对应的 java 版本为8版本
搭建之前确认对应的 scala 版本为2.12.x版本。
[root@node01 ~]# rpm -ivh scala-2.12.11.rpm
[root@node01 ~]# whereis scala
[root@node01 ~]# vim /etc/profile
export SCALA_HOME=/usr/share/scala
export PATH=$SCALA_HOME/bin:$PATH
[root@node01 ~]# source /etc/profile
三台计算机Node01 Node02 Node03都需要安装Scala
启动spark的集群
[root@node01 ~]# cd /opt/yjx/spark-2.4.6/sbin/
[root@node01 sbin]# ./start-all.sh
访问
http://192.168.88.101:8080/
运行案例
spark-submit --master spark://node01:7077 --class org.apache.spark.examples.SparkPi $SPARK_HOME/examples/jars/spark-examples_2.12-2.4.6.jar 10
启动集群
访问
提交任务
spark-submit --master yarn --class org.apache.spark.examples.SparkPi $SPARK_HOME/examples/jars/spark-examples_2.12-2.4.6.jar 10
Standalon 和 Yarn 的任务提交方式图解
提交命令
spark-submit --master spark://node01:7077 --deploy-mode client --class org.apache.spark.examples.SparkPi $SPARK_HOME/examples/jars/spark-examples_2.12-2.4.6.jar 10
执行流程
总结
提交命令
spark-submit --master spark://node01:7077 --deploy-mode cluster --classorg.apache.spark.examples.SparkPi $SPARK_HOME/examples/jars/spark-examples_2.12-2.4.6.jar 10
执行流程
总结
提交命令
spark-submit --master yarn --class org.apache.spark.examples.SparkPi $SPARK_HOME/examples/jars/spark-examples_2.12-2.4.6.jar 10
spark-submit --master yarn–client --class org.apache.spark.examples.SparkPi $SPARK_HOME/examples/jars/spark-examples_2.12-2.4.6.jar 10
spark-submit --master yarn --deploy-mode client --class org.apache.spark.examples.SparkPi $SPARK_HOME/examples/jars/spark-examples_2.12-2.4.6.jar 10
执行流程
版本一:
版本二:
版本三:
总结
提交命令
spark-submit --master yarn --deploy-mode cluster --class org.apache.spark.examples.SparkPi $SPARK_HOME/examples/jars/spark-examples_2.12-2.4.6.jar 10
spark-submit --master yarn-cluster --class org.apache.spark.examples.SparkPi $SPARK_HOME/examples/jars/spark-examples_2.12-2.4.6.jar 10
执行流程
版本一:
版本二:
总结
相同点
作业方式不同
spark 的standalone模式使用的是spark自身的集群管理器
yarn模式是将spark作业运行在yarn上。
多用户支持不同
standalone对于多用户多application支持的不好,只能支持fifo模式进行资源调度,先来的任务先执行,后来的任务就后执行。也可以通过配置,让先来的任务不占用所有资源,给后来的任务留点资源
yarn模式对于多用户多任务支持比较好,arn中有fifo调度器,容量调度器,公平调度器这三种资源分配策略,可以动态实现资源的扩缩,更灵活,更重
Yarn和Spark的Standalone调度模式对比
Yarn | Standalone | 节点功能 |
---|---|---|
ResouceManager | Master | 管理子节点、资源调度、接收任务请求 |
NodeManger | Worker | 管理当前节点,并管理子进程 |
YarnChild | Executor | 运行真正的计算逻辑的(Task) |
Client | Client | 提交app,管理该任务的Executor |
ApplicaitonMaster | ApplicaitonMaster | 管理任务,包含driver程序和运行在集群上的executor程序 |