Spark一之基础

Spark 基础

一、Spark的介绍

1.定义

Spark是一种基于内存的快速、通用、可扩展的大数据分析引擎。

Hadoop基于硬盘

2.Spark VS MapReduce

Spark的诞生仅仅是为了替换早期的Hadoop的MapReduce计算引擎。Spark并没有存储解决方案,在Spark的架构中,底层存储方案依然延续Hadooop的HDFS/Hbase.由于Hadoop的MapReduce是大数据时代出现的第一类大数据分析工具,因为出现比较早仅仅为了满足大数据计算的刚性需求(能够做到对大数据的计算,并且可以保证在一个合理的时间范围内)。因此伴随着科技的进步,互联网的快速发展,人们开始对大数据计算提出了更苛刻要求
在这里插入图片描述

Spark的设计中汲取了Map Reduce的设计经验,在2009 年Spark在加州伯克利AMP实验室诞生,2010年首次开源,2013年6开始在Apache孵化,2014年2月份正式成为Apache顶级项目。由于Spark计算底层引擎使用批处理计算模型实现,非常容易被广大深受MapReduce计算折磨程序员所接受,所以就导致了Spark 的关注度直线提升
在这里插入图片描述

3.Spark内置模块

在这里插入图片描述在这里插入图片描述

Spark Core:实现了Spark的基本功能,包含任务调度、内存管理、错误恢复、与存储系统交互等模块。Spark Core中还包含了对弹性分布式数据集(Resilient Distributed DataSet,简称RDD)的API定义。

Spark SQL:是Spark用来操作结构化数据的程序包。通过Spark SQL,我们可以使用 SQL或者Apache Hive版本的SQL方言(HQL)来查询数据。Spark SQL支持多种数据源,比如Hive表、Parquet以及JSON等。

Spark Streaming:是Spark提供的对实时数据进行流式计算的组件。提供了用来操作数据流的API,并且与Spark Core中的 RDD API高度对应。

Spark MLlib:提供常见的机器学习(ML)功能的程序库。包括分类、回归、聚类、协同过滤等,还提供了模型评估、数据导入等额外的支持功能。

集群管理器:Spark 设计为可以高效地在一个计算节点到数千个计算节点之间伸缩计算。为了实现这样的要求,同时获得最大灵活性,Spark支持在各种集群管理器(Cluster Manager)上运行,包括Hadoop YARN、Apache Mesos,以及Spark自带的一个简易调度器,叫作独立调度器。

二、安装Spark

1.Spark相关地址

1.官网地址

http://spark.apache.org/

2.文档查看地址

http://spark.apache.org/docs/2.4.3/

3.下载地址

https://spark.apache.org/downloads.html

2.重要角色

2.1 Driver/Driver Program(驱动器)

Spark的驱动器是执行开发程序中的main方法的进程。它负责开发人员编写的用来创建SparkContext、创建RDD,以及进行RDD的转化操作和行动操作代码的执行。如果你是用spark shell,那么当你启动Spark shell的时候,系统后台自启了一个Spark驱动器程序,就是在Spark shell中预加载的一个叫作 sc的SparkContext对象。如果驱动器程序终止,那么Spark应用也就结束了。主要负责:

1)把用户程序转为作业(JOB)

2)跟踪Executor的运行状况

3)为执行器节点调度任务

4)UI展示应用运行状况

2.2 Executor(执行器)

Spark Executor是一个工作进程,负责在 Spark 作业中运行任务,任务间相互独立。Spark 应用启动时,Executor节点被同时启动,并且始终伴随着整个 Spark 应用的生命周期而存在。如果有Executor节点发生了故障或崩溃,Spark 应用也可以继续执行,会将出错节点上的任务调度到其他Executor节点上继续运行。主要负责:

1)负责运行组成 Spark 应用的任务,并将结果返回给驱动器进程;

2)通过自身的块管理器(Block Manager)为用户程序中要求缓存的RDD提供内存式存储。RDD是直接缓存在Executor进程内的,因此任务可以在运行时充分利用缓存数据加速运算。

2.3 Spark的提交流程

在这里插入图片描述

3. Standalone模式(伪分布式)

spark-2.4.3-bin-hadoop2.7.tgz(带了hadoop依赖)

spark-2.3.4-bin-without-hadoop.tgz(未带hadoop依赖)

若要使用未带依赖的,应该要hadoop对应jar包位置路径配置在spark配置文件里。

spark–>scala–>jdk(需要安装jdk,不需要安装scala,自带scala)

准备工作:正常安装JDK、Hadoop(启动hdfs)

1)上传并解压spark安装包

[root@spark56 modules]# tar -zxvf spark-2.4.3-bin-hadoop2.7.tgz -C /opt/install/
[root@spark56 install]# mv spark-2.4.3-bin-hadoop2.7/ spark2.4.3
  1. 修改配置文件
[root@spark56 spark2.4.3]# cd conf/
[root@spark56 conf]# mv slaves.template slaves
[root@spark56 conf]# mv spark-env.sh.template spark-env.sh
[root@spark56 conf]# vi slaves
#配置Spark集群节点主机名(伪分布式)(分布式配置work节点名字)
spark56
[root@spark56 conf]# vi spark-env.sh
#声明Spark集群中Master的主机名和端口号
SPARK_MASTER_HOST=spark56
SPARK_MASTER_PORT=7077
  1. 在spark中配置JAVA_HOME
[root@spark56 conf]# cd ..
[root@spark56 spark2.4.3]# cd sbin/
[root@spark56 sbin]#vi spark-config.sh
#在最后增加 JAVA_HOME 配置
export JAVA_HOME=/opt/install/jdk1.8/
  1. 启动spark
[root@spark56 spark2.4.3]# sbin/start-all.sh
[root@spark56 spark2.4.3]# jps
1392 NameNode
9781 Worker    //spark进程
9702 Master	   //spark进程
1546 DataNode
9979 Jps
1742 SecondaryNameNode

spark两种测试方式: bin/spark-shell (基于命令行的方式)

​ bin/spark-submit (基于jar包提交的方式)

bin/spark-shell : 对于一些代码进行测试时使用,学习和测试环境使用

bin/spark-submit: 对于写好的程序打成jar后测试的,生产环境的使用
在这里插入图片描述

方式1(:quit退出)

新建一个a.txt、b.txt如下,并且上传到hdfs之上(hdfs dfs -put a.txt /input	hdfs dfs -put a.txt /input)
a.txt
hello hello hello
world world hello
b.txt
zhangsan lisi lisi
zhangsan laofan lihao
(standalong模式)
[root@spark56 spark2.4.3]# bin/spark-shell --master spark://spark56:7077
scala> sc.textFile("hdfs://spark56:9000/input")
		 .flatMap(_.split(" "))
		 .map((_,1))
		 .groupBy(_._1)
		 .map(t=>(t._1,t._2.size))
		 .collect
res0: Array[(String, Int)] = Array((hello,4), (world,2))
# Web查看
http://spark56:4040
  1. 方式2
参考:开发部署第一个Spark程序部分

4. Spark On Yarn模式

standalone提供的是master和worker

on yarn模式不需要master和worker进程了,而是交给yarn来调用调度资源:

​ yarn中的RM(resource manager)取代master的角色

​ yarn中的NM(node manager)取代worker的角色

准备工作:正常安装JDK、Hadoop(启动hdfs和yarn)

  1. 修改yarn-site.xml文件
<!--是否启动一个线程检查每个任务正使用的物理内存量,如果任务超出分配值,则直接将其杀掉,默认是true -->
<property>
	<name>yarn.nodemanager.pmem-check-enabled</name>
	<value>false</value>
</property>
		
<!--是否启动一个线程检查每个任务正使用的虚拟内存量,如果任务超出分配值,则直接将其杀掉,默认是true -->
<property>
	<name>yarn.nodemanager.vmem-check-enabled</name>
	<value>false</value>
</property>
  1. 修改spark-env.sh,添加如下配置:
注意和standalone的区别,不需要在配置SPARK_MASTER_HOST和SPARK_MASTER_PORT 
# yarn模式把master和worker两个进程结束
# yarn模式把这两行注释掉加上下面的
# 和SPARK_HISTORY_OPTS(历史服务器)可以继续使用
[root@spark56 conf]# vi spark-env.sh
YARN_CONF_DIR=/opt/install/hadoop2.9.2/etc/hadoop/
  1. 执行一个程序
#方式1
[root@spark56 spark2.4.3]# bin/spark-shell --master yarn
scala> sc.textFile("hdfs://spark56:9000/input/a.txt").flatMap(_.split(" ")).collect


#方式2
[root@spark56 spark2.4.3]# bin/spark-submit --master yarn --class day1.test.SparkWordCount /opt/app/spark-1.0-SNAPSHOT.jar

jar包对应的程序中设置master改为yarn 
new SparkConf().setMaster("yarn").setAppName("wc")

注意:在执行任务前先启动hdfs和yarn

4.1Yarn与Standalone的区别
satandalone							yarn
	master:处理client请求,调度资源		resourcemanager:处理client请求,调度资源	
	worker执行task任务的				  nodemanager:执行task任务
	
Yarn流行高于standalong的原因:
1.基本还是有Hadoop环境
2.standalone模型只能调度spark任务。
  yarn模型可以调度更多的任务。

5.JobHistoryServer配置(查看历史运行任务)

  1. 在spark的conf文件下修改spark-default.conf.template名称, 修改spark-default.conf文件,开启Log
[root@spark56 conf]# mv spark-defaults.conf.template spark-defaults.conf
[root@spark56 conf]# vi spark-defaults.conf
spark.eventLog.enabled           true
spark.eventLog.dir               hdfs://spark56:9000/spark-logs

注意:HDFS上的目录需要提前存在。

[root@spark56 ~]# hdfs dfs -mkdir /spark-logs

  1. 修改spark-env.sh文件,添加如下配置
[root@spark56 conf]# vi spark-env.sh
SPARK_HISTORY_OPTS="-Dspark.history.fs.logDirectory=hdfs://spark56:9000/spark-logs"
  1. 启动对应的服务
[root@spark56 spark2.4.3]# sbin/start-history-server.sh
[root@spark56 spark2.4.3]# jps
1392 NameNode
9781 Worker
9702 Master
120054 Jps
1546 DataNode
119946 HistoryServer		 # 对应启动的进程名称
1742 SecondaryNameNode
  1. 查看历史服务

http://spark56:18080

只有配置了JobHistoryServer才能看到过去运行过的任务。

spark-shell只有在退出的时候才能在历史服务器中看到,如果没有退出需要在spark56:4040那查看运行中的任务

三、开发部署第一个Spark程序

​ Spark Shell仅在测试和验证我们的程序时使用的较多,在生产环境中,通常会在IDE中编写程序,然后打成jar包,然后提交到集群,最常用的是创建一个Maven项目,利用Maven来管理jar包的依赖。

  1. 创建一个maven项目,并且导入相关依赖
<!-- spark依赖-->
<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-core_2.11</artifactId>
    <version>2.4.3</version>
</dependency>
<build>
    <plugins>
        <!-- maven项目对scala编译打包 -->
        <plugin>
            <groupId>net.alchim31.maven</groupId>
            <artifactId>scala-maven-plugin</artifactId>
            <version>4.0.1</version>
            <executions>
               <execution>
                   <id>scala-compile-first</id>
                   <phase>process-resources</phase>
                   <goals>
                       <goal>add-source</goal>
                       <goal>compile</goal>
                   </goals>
              </execution>
            </executions>
        </plugin>
    </plugins>
</build>
  1. 编写Spark Driver代码
package day1.test

import org.apache.spark.{SparkConf, SparkContext}

object SparkWordCount {
  def main(args: Array[String]): Unit = {
    //1.创建sparkContext对象
    val sparkConf = new SparkConf().setMaster("spark://spark56:7077").setAppName("wc")
    val sc = new SparkContext(sparkConf)
    //读取hdfs上的文件,进行WordCount单词统计,如果是分布式集群情况下有可能报错(可能某一阶段某一台work并没有在自己本地上找到文件)
    //val rdd1 = sc.textFile("file:///opr/a.txt")
    //2.读取hdfs上的文件,进行WordCount单词统计
    val rdd1 = sc.textFile("hdfs://spark56:9000/input")
    val rdd2 = rdd1.flatMap(_.split(" ")).map((_, 1)).groupBy(v => v._1).map(v => (v._1, v._2.size))
    //将计算结果保存在hdfs之上,目录不允许存在,自动创建
    rdd2.saveAsTextFile("hdfs://spark56:9000/results")
    //3.关闭sparkContext对象
    sc.stop()
  }
}
  1. 执行mvn pacake指令打包程序,并上传到linux中

  2. 将打包的程序上传到远程集群执行以下脚本

[root@spark56 spark2.4.3]# bin/spark-submit --master spark://spark56:7077 --class day1.test.SparkWordCount  /opt/app/spark-1.0-SNAPSHOT.jar

spark-submit方式适用于生产环境,当然spark也支持本地测试,无需构建spark环境即可测试spark代码。

四、本地模式

本地Spark程序调试需要使用local提交模式,即将本机当做运行环境,Master和Worker都为本机。

创建SparkConf的时候设置额外属性,表明本地执行:

val conf = new SparkConf().setAppName("wc").setMaster("local[*]")

local: 只启动一个executor

local[k] : 启动k个executor

local[*] : 启动跟cpu数目相同的executor

代码如下

package day1.test

import org.apache.spark.{SparkConf, SparkContext}

object SparkWordCount2 {
  def main(args: Array[String]): Unit = {
    //1.创建sparkContext对象
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("wc")
    val sc = new SparkContext(sparkConf)
    //2.读取hdfs上的文件,进行WordCount单词统计
    //val rdd1 = sc.textFile("hdfs://spark56:9000/input")
    val rdd1 = sc.textFile("file:///D:/test")
    val rdd2 = rdd1.flatMap(_.split(" ")).map((_, 1)).groupBy(v => v._1).map(v => (v._1, v._2.size))
    //将计算结果保存在hdfs之上,目录不允许存在,自动创建
    rdd2.saveAsTextFile("file:///D:/results")
    //3.关闭sparkContext对象
    sc.stop()
  }
}

xt(sparkConf)
//2.读取hdfs上的文件,进行WordCount单词统计
//val rdd1 = sc.textFile(“hdfs://spark56:9000/input”)
val rdd1 = sc.textFile(“file:///D:/test”)
val rdd2 = rdd1.flatMap(.split(" ")).map((, 1)).groupBy(v => v._1).map(v => (v._1, v._2.size))
//将计算结果保存在hdfs之上,目录不允许存在,自动创建
rdd2.saveAsTextFile(“file:///D:/results”)
//3.关闭sparkContext对象
sc.stop()
}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值