spark工作原理:
RDD(Resillient Distributed ):弹性分布式数据集
RDD是在内存中类似于MapReduce的计算逻辑
1. RDD简介:
1.1 什么是RDD
RDD通常通过Hadoop上的文件,即HDFS文件进行创建,也可以通过程序中的集合来创建
RDD是Spark提供的核心抽象,全称为Resillient Distributed Dataset,即弹性分布式数据集
1.2 RDD的特点
- 弹性:RDD数据默认情况下存放在内存中,但是在内存资源不足时,Spark也会自动将RDD数据写入磁盘
- 分布式:RDD在抽象上来说是一种元素数据的集合,它是被分区的,每个分区分布在集群中的不同节点上,从而让RDD中的数据可以被并行操作
- 容错性:RDD最重要的特性就是提供了容错性,可以自动从节点失败中恢复过来
如果某个节点上的RDD partition,因为节点故障,导致数据丢了,那么RDD会自动通过自己的数据来源重新计算该partition的数据
2. Spark架构相关进程
2.1 Driver
我们编写的Spark程序就在Driver(进程)上,由Driver进程负责执行
Driver进程所在的节点可以是Spark集群的某一个节点或者就是我们提交Spark程序的客户端节点
具体Driver进程在哪个节点上启动是由我们提交任务时指定的参数决定的,这个后面我们会详细分析
2.2 Master
集群的主节点中启动的进程
主要负责集群资源的管理和分配,还有集群的监控等
2.3 Worker
集群的从节点中启动的进程
主要负责启动其它进程来执行具体数据的处理和计算任务
2.4 Executor
此进程由Worker负责启动,主要为了执行数据处理和计算
2.5 Task
是有Executor负责启动的线程,他是真正干活的
3. spark原理
1. 首先我们在spark的客户端机器上通过driver进程执行我们的Spark代
当我们通过spark-submit脚本提交Spark任务的时候Driver进程就启动了。
2. Driver进程启动之后,会做一些初始化的操作,会找到集群master进程,对Spark应用程序进行注册
3. 当Master收到Spark程序的注册申请之后,会发送请求给Worker,进行资源的调度和分配
4. Worker收到Master的请求之后,会为Spark应用启动Executor进程
会启动一个或者多个Executor,具体启动多少个,会根据你的配置来启动
5. Executor启动之后,会向Driver进行反注册,这样Driver就知道哪些Executor在为它服务了
6. Driver会根据我们对RDD定义的操作,提交一堆的task去Executor上执行
task里面执行的其实就是具体的map、flatMap这些操
4. spark 使用scala开发wordcounts
object WordCountScala {
def main(args: Array[String]): Unit = {
val conf = new SparkConf()
//local表示在本地执行
conf.setMaster("local")
//设置任务名称
conf.setAppName("WordCountScala")
//构建 SparkContext
val sc = new SparkContext(conf)
// 加载数据
val linesRDD: RDD[String] = sc.textFile("data/testdata.txt")
//对数据进行切割,把一行数据切分成一个一个的单词
val spliteWords: RDD[String] = linesRDD.flatMap(line => {
line.split(" ")
})
// 迭代words,将每个word转化为(word,1)这种形式
val mapWords: RDD[(String, Int)] = spliteWords.map((_, 1))
// 根据key(其实就是word)进行分组聚合统计
val value: RDD[(String, Int)] = mapWords.reduceByKey(_ + _)
// 将结果打印到控制台
value.foreach(println)
//第七步:停止SparkContext
sc.stop()
}
}
5. spark 任务提交方式
- windows环境下在idea中执行,方便在本地环境调试代码
- 使用spark-submit提交到集群执行【实际工作中的方式】
- 使用spark-shell,方便在集群环境调试代码