Spark 程序设计详解
一、 Spark角色介绍
Spark是基于内存计算的大数据并行计算框架。因为其基于内存计算,比Hadoop中MapReduce计算框架具有更高的实时性,同时保证了高效容错性和可伸缩性。从2009年诞生于AMPLab到现在已经成为Apache顶级开源项目,并成功应用于商业集群中,学习Spark就需要了解其架构。
Spark架构图如下:
Spark架构使用了分布式计算中master-slave模型,master是集群中含有master进程的节点,slave是集群中含有worker进程的节点。
u Driver Program :运⾏main函数并且新建SparkContext的程序。
u Application:基于Spark的应用程序,包含了driver程序和集群上的executor。
u Cluster Manager:指的是在集群上获取资源的外部服务。目前有三种类型
(1)Standalone: spark原生的资源管理,由Master负责资源的分配
(2)Apache Mesos:与hadoop MR兼容性良好的一种资源调度框架
(3)Hadoop Yarn: 主要是指Yarn中的ResourceManager
二、 初识Spark程序
1 执行第一个spark程序
普通模式提交任务:
bin/spark-submit \ --class org.apache.spark.examples.SparkPi \ --master spark://node1:7077 \ --executor-memory 1G \ --total-executor-cores 2 \ examples/jars/spark-examples_2.11-2.1.3.jar \ 10 |
该算法是利用蒙特·卡罗算法求圆周率PI,通过计算机模拟大量的随机数,最终会计算出比较精确的π。
高可用模式提交任务:
在高可用模式下,因为涉及到多个Master,所以对于应用程序的提交就有了一点变化,因为应用程序需要知道当前的Master的IP地址和端口。这种HA方案处理这种情况很简单,只需要在SparkContext指向一个Master列表就可以了,
如spark://host1:port1,host2:port2,host3:port3,应用程序会轮询列表,找到活着的Master。
bin/spark-submit \ --class org.apache.spark.examples.SparkPi \ --master spark://node1:7077,node2:7077,node3:7077 \ --executor-memory 1G \ --total-executor-cores 2 \ examples/jars/spark-examples_2.11-2.1.3.jar \ 10 |
2 启动Spark-Shell
spark-shell是Spark自带的交互式Shell程序,方便用户进行交互式编程,用户可以在该命令行下用scala编写spark程序。
2.1 运行spark-shell --master local[N] 读取本地文件
单机模式:通过本地N个线程跑任务,只运行一个SparkSubmit进程。
(1)需求
读取本地文件,实现文件内的单词计数。本地文件words.txt 内容如下:
hello me hello you hello her |
(2)运行spark-shell --master local[2]
观察启动的进程:
(3)编写scala代码
sc.textFile("file:///root///words.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).collect |
代码说明:
sc:Spark-Shell中已经默认将SparkContext类初始化为对象sc。用户代码如果需要用到,则直接应用sc即可。
textFile:读取数据文件
flatMap:对文件中的每一行数据进行压平切分,这里按照空格分隔。
map:对出现的每一个单词记为1(word,1)
reduceByKey:对相同的单词出现的次数进行累加
collect:触发任务执行,收集结果数据。
Worker Node: 集群中任何可以运行Application代码的节点,在Standalone模式中指的是通过slaves文件配置的Worker节点,在Spark on Yarn模式下就是NodeManager节点
Executor:是在一个worker node上为某应用启动的⼀个进程,该进程负责运行任务,并且负责将数据存在内存或者磁盘上。每个应用都有各自独立的executor。
Task :被送到某个executor上的工作单元。
(4)观察结果:
2.2 运行spark-shell --master local[N] 读取HDFS上数据
(1)、整合spark和HDFS,修改配置文件
在spark-env.sh ,添加HADOOP_CONF_DIR配置,指明了hadoop的配置文件后,默认它就是使用的hdfs上的文件
export HADOOP_CONF_DIR=/export/servers/hadoop/etc/hadoop
(2)、再启动启动hdfs,然后重启spark集群
(3)、向hdfs上传一个文件到hdfs://node1:9000/words.txt
(4)、在spark shell中用scala语言编写spark程序
sc.textFile("/words.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).collect |
2.3 运行spark-shell 指定具体的master地址
(1)需求:
spark-shell运行时指定具体的master地址,读取HDFS上的数据,做单词计数,然后将结果保存在HDFS上。
(2)执行启动命令:
spark-shell \
--master spark://node1:7077 \
--executor-memory 1g \
--total-executor-cores 2
参数说明:
--master spark://node1:7077 指定Master的地址
--executor-memory 1g 指定每个worker可用内存为1g
--total-executor-cores 2 指定整个集群使用的cup核数为2个
注意:
如果启动spark shell时没有指定master地址,但是也可以正常启动spark shell和执行spark shell中的程序,其实是启动了spark的local模式,该模式仅在本机启动一个进程,没有与集群建立联系。
(2)编写scala代码
sc.textFile("/words.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).saveAsTextFile("/wc") |
saveAsTextFile:保存结果数据到文件中
(3)查看hdfs上结果
3.在IDEA中编写WordCount程序
spark-shell仅在测试和验证我们的程序时使用的较多,在生产环境中,通常会在IDEA中编写程序,然后打成jar包,最后提交到集群。最常用的是创建一个Maven项目,利用Maven来管理jar包的依赖。
(1).创建一个项目
(2).选择Maven项目,然后点击next
(3).填写maven的GAV,然后点击next
(4)填写项目名称,然后点击finish
(5).创建好maven项目后,点击Enable Auto-Import
(6)配置Maven的pom.xml
<properties>
<scala.version>2.11.8</scala.version>
<spark.version>2.1.3</spark.version>
</properties>
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>${spark.version}</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/scala</sourceDirectory>
<testSourceDirectory>src/test/scala</testSourceDirectory>
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.2.2</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
<configuration>
<args>
<arg>-dependencyfile</arg>
<arg>${project.build.directory}/.scala_dependencies</arg>
</args>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass></mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
|
(7)添加src/main/scala和src/test/scala,与pom.xml中的配置保持一致
(8)新建一个scala class,类型为Object
(9).编写spark程序
package cn.test.spark
|
(10).使用Maven打包:
点击idea右侧的Maven Project选项
点击Lifecycle,选择package,然后点击Run Maven Build
(11).选择编译成功的jar包,并将该jar上传到Spark集群中的某个节点上
(12).首先启动hdfs和Spark集群
启动hdfs
/export/servers/hadoop/sbin/start-dfs.sh
启动spark
/export/servers/spark/sbin/start-all.sh
(13).使用spark-submit命令提交Spark应用(注意参数的顺序)
spark-submit \
--class cn.test.spark.WordCount \
--master spark://node1:7077 \
--executor-memory 1g \
--total-executor-cores 2 \
/root/spark-1.0-SNAPSHOT.jar \
/words.txt \
/spark_out
这里通过spark-submit提交任务到集群上。用的是spark的Standalone模式
Standalone模式是Spark内部默认实现的一种集群管理模式,这种模式是通过集群中的Master来统一管理资源。
1) 查看Spark的web管理界面
地址:hadoop-001:8080
2) 查看HDFS上的结果文件
hdfs dfs -cat /spark_out/part*
(hello,4)
(me,2)
(you,3)
(her,1)
4 使用java语言编写spark wordcount程序
package cn.gec;
|