1.spark 是什么?
基于内存的分布式并行的计算框架(还有 mapReduce, storm(目前用的少))
spark 的吞吐量更大,但是有秒级别的延迟(storm 是毫秒级的延迟,Flink 也是毫秒级的延迟)
executor : 是一个进程,装载在container里运行 ,executor 分配的内存是一个G
---------------------------------------------------
2.spark 的四大组件
Spark四大组件包括Spark Streaming、Spark SQL、Spark MLlib和Spark GraphX。它们的主要应用场景是:
Spark Streaming:
Spark Streaming基于微批量方式的计算和处理,可以用于处理实时的流数据。它使用DStream,简单来说就是一个弹性分布式数据集(RDD)系列,处理实时数据。
Spark SQL:
Spark SQL可以通过JDBC API将Spark数据集暴露出去,而且还可以用传统的BI和可视化工具在Spark数据上执行类似SQL的查询。用户还可以用Spark SQL对不同格式的数据(如JSON,Parquet以及数据库等)执行ETL,将其转化,然后暴露给特定的查询。
Spark MLlib:
MLlib是一个可扩展的Spark机器学习库,由通用的学习算法和工具组成,包括二元分类、线性回归、聚类、协同过滤、梯度下降以及底层优化原语。用于机器学习和统计等场景
Spark GraphX:
GraphX是用于图计算和并行图计算的新的(alpha)Spark API。通过引入弹性分布式属性图(Resilient Distributed Property Graph),一种顶点和边都带有属性的有向多重图,扩展了Spark RDD。为了支持图计算,GraphX暴露了一个基础操作符集合(如subgraph,joinVertices和aggregateMessages)和一个经过优化的Pregel API变体。此外,GraphX还包括一个持续增长的用于简化图分析任务的图算法和构建器集合。
---------------------------------------------------
3. spark 的组件(spark 所有得环境配置都在spark-env得配置文件里面)
spark中driver 和executor的理解:
(1) 如果我有三台机器 A , B , C 我在B机器上执行了spark-shell ,那么B机器就会成为一个driver ,而 A C机器就是executor
(2) 根据clusterManager的不同,spark可以分成四种不同的运行模式,standalone、local cluster、spark on yarn 和spark on mesos
(3) 在Spark中由SparkContext负责与ClusterManager通讯,进行资源的申请,任务的分配和监控等。当Executor部分运行完毕后,Driver同时负责将SaprkContext关闭,通常SparkContext代表Driver.
整理执行过程:executor是workerNode上启动的一个进程
SparkContext 找 ClusterManager 申请资源(需要多少CPU,内存等)→ClusterManager 去找workerNode并启动executor,并介绍executor给driver →driver 根据任务分成一批一批的task,将task给executor执行→executor 接收到task后准备task运行时的依赖并执行,把执行结果返回给driver→
driver会根据返回的task状态不断只会下一步工作直到task结束为止
---------------------------------------------------
4. Spark 核心 RDD :弹性的分布式数据集(只读)
一 : 创建RDD 的方式:
(1). sparkContext (spark2.0 以下版本用 sparkContext , spark2.0以后使用了 sparkSession 来构建RDD sparkSession中包含SparkContext)
(2). 用已有的RDD来创建 如:val b = a.map(x=>(x,1))
(3). 定义一个scala数组 如: val c = sc.parallelize(1 to 10,1)
(4).有一个已经存在的RDD通过持久化操作生成
如: val d= a.persist(), a.saveAsHadoopFile("") (persist 相当于cache)
spark 针对RDD提供两个操作 有两个算子:1. action (ex:count ) 2.transformation(filter ,采用懒策略) 能够返回一个新得RDD
transformation 是RDD转换之间得变换 (例如 :map , filter , flatMap , sample , groupByKey , reduceByKey , union , join , cogroup , mapValues , sort , partitionBy)
action 是对数据执行一定的操作 (例如 : count , collect , reduce , lookup, save)
例子:textFile.filter(line => line.contains("Spark")).count()
val wordCounts = textFile.flatMap(line => line.split(" ")).map(word => (word, 1)).reduceByKey((a, b) => a + b)
二 :每个RDD 都包含数据分块(partition)集合
与父RDD 的依赖关系(重点)(RDDA=>RDDB)
宽依赖:B的每一个partition 都依赖于A的所有partition
比如:groupByKey,reduceByKey, join(父RDD不是hash-partitioned ),partitionBy只要有shuffle 过程就是宽依赖
窄依赖:B的每一个partition 都依赖于A的常数个partition(一对一,多对一)
比如:map , filter, union , join(父RDD是hash-partitioned ), mapPartitions, mapValues
跑spark的时候 会出现 stage, stage 是用来划分任务的,(把窄依赖 放在一遍 , 根据宽依赖来划分stage)
每个stage的内部,尽可能 多包含一组具有窄依赖关系转化并将他们并行化(pipeline)
每一个partition计算就是一个task,task 是调度的基本单位
解释一下Stage是什么:
在Spark中,一段程序实际上构造了一个由相互依赖的多个RDD组成的有向无环图(DAG)。spark会根据RDD之间的依赖关系将DAG图划分为不同的阶段Stage,对于窄依赖,由于partition依赖关系的确定性,partition的转换处理就可以在同一个线程里完成,窄依赖就被spark划分到同一个stage中,如图RDD C、D、E、F它们都在Stage2中,而对于宽依赖,只能等父RDD shuffle处理完成后,下一个stage才能开始接下来的计算,因此宽依赖要单独划分一个Stage
三 :容错
1. 如果task失败,AM会重新分配task
2.如果task依赖的上层partition数据已经失效,会将其依赖的partition计算任务再重算一遍
3.宽依赖中被依赖partition,可以将数据保存HDFS,以便快速重构checkpoint
(窄依赖只依赖上层partition,恢复代价较少;宽依赖依赖上层所有的partition,如果数据丢失山曾所有partition 要重算)
4.可以指定保存一个RDD的数据至节点的cache中,如果内存不够,会LRU释放一部分仍有重构的可能
宽依赖出错了 肯定会出现重复计算