使用Spark编写一个简单的word count单词统计及Spark基本架构及运行原理

1、Spark基本架构及原理

Spark:spark只是一个计算框架,它的能力是在现有数据的基础上提供一个高性能的计算引擎,然后提供一些上层的处理工具比如做数据查询的Spark SQL、做机器学习的MLlib等;而hadoop的功能则更加全面,它是包括了数据存储(HDFS)、任务计划和集群资源管理(YARN)以及离线并行计算(MapReduce)的一整套技术栈。

Spark架构示意图
在这里插入图片描述
Spark的核心库是spark core。还有其他的是个库分别为Spark SQL、Spark Streaming、MLlib、Graphx。

  • Spark Core:
    包含Spark的基本功能,包含任务调度,内存管理,容错机制等,内部定义了RDDs(弹性分布式数据集),提供了很多APIs来创建和操作这些RDDs。为其他组件提供底层的服务。
  • Spark SQL:
    Spark处理结构化数据的库,就像Hive SQL,Mysql一样,企业中用来做报表统计。
  • Spark Streaming:
    实时数据流处理组件,类似Storm。Spark Streaming提供了API来操作实时流数据。企业中用来从Kafka接收数据做实时统计。
  • MLlib:
    一个包含通用机器学习功能的包,Machine learning lib包含分类,聚类,回归等,还包括模型评估和数据导入。MLlib提供的上面这些方法,都支持集群上的横向扩展。
  • Graphx: 处理图的库(例如,社交网络图),并进行图的并行计算。像Spark Streaming,Spark SQL一样,它也继承了RDD API。它提供了各种图的操作,和常用的图算法,例如PangeRank算法。

只要掌握Spark一门编程语言就可以编写不同应用场景的应用程序(批处理,流计算,图计算等)。Spark主要用来代替Hadoop的MapReduce部分。

为什么要用spark来代替hadoop?

Hadoop MapReduce缺点:

表达能力有限
磁盘IO开销大,任务之间的衔接涉及IO开销
延迟高,Map任务要全部结束,reduce任务才能开始。

Spark借鉴Hadoop MapReduce优点的同时,解决了MapReuce所面临的问题,Spark所采用的Executor有如下优点:

Spark的计算模式也属于MapReduce,但不局限于Map和Reduce操作,还提供多种数据集操作类型,编程模型比Hadoop MapReduce更灵活。Spark提供了内存计算,可将中间结果放到内存中,对于迭代运算效率更高。

spark可以利用多线程来执行具体的任务减少任务的启动开销;

Executor中有一个BlockManager存储模块,会将内存和磁盘共同作为存储设备,有效减少IO开销;

2、Spark的运行框架及流程

spark运行架构
在这里插入图片描述

  • Application:用户编写的Spark应用程序。
  • Driver:Spark中的Driver即运行上述Application的main函数并创建SparkContext,创建SparkContext的目的是为了准备Spark应用程序的运行环境,在Spark中有SparkContext负责与ClusterManager通信,进行资源申请、任务的分配和监控等,当Executor部分运行完毕后,Driver同时负责将SparkContext关闭。
  • Executor:是运行在工作节点(WorkerNode)的一个进程,负责运行Task。
  • RDD:弹性分布式数据集,是分布式内存的一个抽象概念,提供了一种高度受限的共享内存模型。
  • DAG:有向无环图,反映RDD之间的依赖关系。
  • Task:运行在Executor上的工作单元。
  • Job:一个Job包含多个RDD及作用于相应RDD上的各种操作。
  • Stage:是Job的基本调度单位,一个Job会分为多组Task,每组Task被称为Stage,或者也被称为TaskSet,代表一组关联的,相互之间没有Shuffle依赖关系的任务组成的任务集。
  • Cluter Manager:指的是在集群上获取资源的外部服务。目前有三种类型
    1)Standalon : spark原生的资源管理,由Master负责资源的分配
    2)Apache Mesos:与hadoop MR兼容性良好的一种资源调度框架
    1)Hadoop Yarn: 主要是指Yarn中的ResourceManager

当执行一个Application时,Driver会向集群管理器申请资源,启动Executor,并向Executor发送应用程序代码和文件,然后在Executor上执行Task,运行结束后,执行结果会返回给Driver,或者写到HDFS或者其它数据库中。

Spark详细运行过程

在这里插入图片描述

  1. 为应用构建起基本的运行环境,即由Driver创建一个SparkContext进行资源的申请、任务的分配和监控
  2. 资源管理器为Executor分配资源,并启动Executor进程
  3. SparkContext根据RDD的依赖关系构建DAG图,DAG图提交给DAGScheduler解析成Stage,然后把一个个TaskSet提交给底层调度器TaskScheduler处理。
    Executor向SparkContext申请Task,TaskScheduler将Task发放给Executor运行并提供应用程序代码。
  4. Task在Executor上运行把执行结果反馈给TaskScheduler,然后反馈给DAGScheduler,运行完毕后写入数据并释放所有资源。

Spark运行架构特点:

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

宽依赖与窄依赖

  1. 宽依赖:表现为存在一个父RDD的一个分区对应一个子RDD的多个分区。

  2. 窄依赖:表现为一个父RDD的分区对应于一个子RDD的分区或者多个父RDD的分区对应于一个子RDD的分区。

在这里插入图片描述

2、Spark简单示例 word count单词统计

前面介绍了Spark的基本组成架构及运行原理,接下来让我们一起编写一个Spark程序吧。

工作准备
1.搭建Spark开发环境使用eclipse软件开发
2.java的jdk版本要求1.8以上,没有的可以去下载1.8版本的进行安装
3.安装Scala,不会安装可以自行百度。或者点击下方下载eclipse。已经安装好Scala,解压即可使用。只需要自己在本机安装jdk1.8及以上的版本。

eclipse资源:

链接:https://pan.baidu.com/s/1T_SA81mO115CMdl0uZn16A
提取码:x9yi

编写Spark程序,打开eclipse创建Scala项目

在这里插入图片描述
新建好后,窗体左边就会出现下图项目文件列表,我们需要修改一下Scala的依赖jar包的版本,修改为2.11的版本,鼠标右键单机,点击Properties.

在这里插入图片描述

选择最后一个2.11.11版本的。
在这里插入图片描述
在这里插入图片描述
然后导入需要的Spark的jar包,找到你的jar文件夹,将所有jar包导入进去。点击下方链接下载需要的jar包
jar下载链接:https://pan.baidu.com/s/1bqf15nZmGLtlSbFqfiDrMw
提取码:a6fw
在这里插入图片描述
做完以上步骤以后我们就可以开始编写我的的Spark程序了。
word count单词统计程序代码如下:

import org.apache.spark.SparkConf
import org.apache.spark.SparkContext


object word_Count {
   def main(args: Array[String]): Unit = {
     
     //1.sc
     //System.setProperty("hadoop.home.dir", "C:\\Users\\Administrator\\Desktop\\Spark\\spark-2.0.2-bin-hadoop2.7")
     var conf = new SparkConf();
     conf.setMaster("local[*]").setAppName("spark");    //本机 运行
     var sc = new SparkContext(conf);          //创建spark的运行环境
     //sc.setLogLevel("WARN");
     
     //2.sc.textFile->RDD
     var path="src/data/data";        //数据存放路径,
     var filedtad_rdd = sc.textFile(path,2);
     //3.rdd.map word->(w,1)
     
     //数据清洗
     var word_rdd = filedtad_rdd.flatMap(_.split("\\W+")).map(x=>(x,1)).reduceByKey(_+_).map(_.swap).sortByKey(false);
     println(word_rdd.count());
     
     //rdd.reduce->w->sum
     //数据清洗后输出
     word_rdd.foreach{line =>
       println("word="+line._2+",sum="+line._1)
       
       }
     
    
     print(filedtad_rdd.count())
     print("end..............................................");
     
   } 
}

介绍及图片来自博客:https://blog.csdn.net/zxc123e/article/details/79912343
https://blog.csdn.net/weixin_42418774/article/details/90677860

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值