【十八掌●武功篇】第十六掌:Spark之简介、安装、Demo

这一篇博文是【大数据技术●降龙十八掌】系列文章的其中一篇,点击查看目录:这里写图片描述大数据技术●降龙十八掌


系列文章:
【十八掌●武功篇】第十六掌:Spark之Scala安装和HelloWorld
【十八掌●武功篇】第十六掌:Spark之Scala语法快速概览
【十八掌●武功篇】第十六掌:Spark之简介、安装、Demo
【十八掌●武功篇】第十六掌:Spark之RDD简介

一、 Spark功能和优势

1. Spark功能

Spark类似于MapReduce,是另一种分布式计算框架,由于MapReduce最大的痛点在于IO,包括硬盘IO和网络IO都成了限制计算的瓶颈,Spark是使用内存来计算,所以Spark是一种内存计算框架。将中间结果存入内存中,大大提高了计算的速度。不同于MapReduce只有map和reduce,Spark提供了上百种操作,功能强大。

2. Spark处理数据分三步走

(1)读取数据:读取数据一般是从HDFS上读取数,如sc.textfile(‘/user/input’)

  • 对于Spark Core来说,将数据变为RDD。
  • 对于Spark Sql来说,是将数据变为DataFrame
  • 对于Streaming来说,将数据变为DStream

(2) 处理数据

  • 对于Spark Core来说,调用RDD的一系列方法。
  • 对于Spark Sql来说,是调用df的一系列方法
  • 对于Streaming来说,是调用dstream一系列方法

这些方法大部分是高阶函数。使用各种方法来在内存中处理数据。

(3) 输出数据:输出数据也大部分是存入硬盘。

sc.SaveAsTextFile
resultDF.write.jdbc()
resultDStream.foreach(Redis\HBase\)
3. Spark优势

Spark是对于海量数据的快速通用引擎。它的优势如下:

(1) 快

Spark运行快的原因一是因为运行过程中将中间结果存入内存,二是因为Spark运行前会将运行过程生成一张DAG图(有向无环图)。
当处理的源数据在文件中时,比Hadoop快10倍,当处理的源数据在内存中时,比Hadoop快100倍。

(2) 通用

可以使用Core/SQL/Streaming/Graphx/MLib/R/StructStreaming(2.0)等进行Spark计算。
处理的数据通用:可以处理HDFS/Hive/HBase/ES、JSON/JDBC等数据
Spark运行模式:Spark可以运行在本地模式、集群模式,集群模式时,可以运行在YARN上、Mesos上、Standalone集群上、云端

(3) 使用简单

可以使用Python、Scala、Java等开发。

二、 Spark与MapReduce的比较

比较项MapReduceSpark
数据存储结构磁盘HDFS文件系统使用内存构建弹性分布式数据集RDD对数据进行运算和缓存
编程范式Map+ReduceDAG(有向无环图):Transformation+action
中间结果存储中间结果落地磁盘,IO及序列化反序列化代价比较大中间结果存储在内存中,速度比磁盘多几个数量级
运行方式Task以进程方式维护,任务启动慢Task以线程方式维护,任务启动快

三、 Spark源码编译

1、 下载Spark源码

Spark源码下载:http://spark.apache.org/downloads.html
我们这里选择Spark1.6.1的源码进行编译。

这里写图片描述

2、 编译要求

Spark编译官方文档地址为:http://spark.apache.org/docs/1.6.1/building-spark.html
Spark源码编译有三种方式:SBT编译、Maven编译、打包编译
官方文档上讲到Spark1.6.1编译要求Maven版本最低是3.3.3,Java版本最低是7。

3、 注意事项

(1) 修改make-distribution.sh文件

make-distribution.sh在源码的根目录下,脚本里有动态查找Spark版本、Scala版本、Hadoop版本、Hive版本的代码,如果编译时去计算会很慢,可以直接将版本写死,可以提高编译速度。

原来的配置:
VERSION=$("$MVN" help:evaluate -Dexpression=project.version $@ 2>/dev/null | grep -v "INFO" | tail -n 1)
SCALA_VERSION=$("$MVN" help:evaluate -Dexpression=scala.binary.version $@ 2>/dev/null\
    | grep -v "INFO"\
    | tail -n 1)
SPARK_HADOOP_VERSION=$("$MVN" help:evaluate -Dexpression=hadoop.version $@ 2>/dev/null\
    | grep -v "INFO"\
    | tail -n 1)
SPARK_HIVE=$("$MVN" help:evaluate -Dexpression=project.activeProfiles -pl sql/hive $@ 2>/dev/null\
    | grep -v "INFO"\
    | fgrep --count "<id>hive</id>";\
    # Reset exit status to 0, otherwise the script stops here if the last grep finds nothing\
    # because we use "set -o pipefail"
    echo -n)
修改为:
VERSION=1.6.1
SCALA_VERSION=2.10.4
SPARK_HADOOP_VERSION=2.5.0-cdh5.3.6
SPARK_HIVE=1

这里版本号一定要跟实际的情况一致。
VERSION是Spark的版本号
SPARK_HIVE为1是支持Hive,0是不支持hive

(2) 配置镜像

[hadoop@spark01-61cdh apache-maven-3.3.3]$ vim /opt/modules/apache-maven-3.3.3/conf/settings.xml
<mirror>
      <id>mirrorId</id>
      <mirrorOf>repositoryId</mirrorOf>
      <name>Human Readable Name for this Mirror.</name>
      <url>http://my.repository.com/repo/path</url>
</mirror>

(3) 修改下域名解析服务器配置

[hadoop@spark01-61cdh apache-maven-3.3.3]$ sudo vim /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4
4、 mvn编译
[hadoop@spark01-61cdh spark-1.6.1]$ mvn clean package -DskipTest -Phadoop-2.4 -Dhadoop.version=2.5.0 -Pyarn -Phive -Phive-thriftserver -Dmaven.test.skip=true -Dmaven.test.skip=true -e
5、 make-distribution进行打包编译

命令参数说明

./make-distribution.sh –name chybin-spark-1.6.1-bin-2.5.0.tar.gz –tgz -Psparkr -Phadoop-2.5 -Phive -Phive-thriftserver –Pyarn

  • name参数是指编译完成后tar包的名称,比如spark-1.6.1-bin-2.5.0.tar.gz
  • -Phadoop-2.5是指使用hadoop2.5版本
  • -Phive是指定spark支持hive
  • -Phive-thriftserver是指定支持hive-thriftserver
  • -Pyarn是指定支持yarn

四、 安装Spark(本地部署模式)

1、 解压spark tar包
[hadoop@spark01-61cdh software]$ tar -zxf /opt/software/spark-1.6.1-bin-2.5.0-cdh5.3.6.tgz -C /opt/modules
2、 检查环境
检查Java是否已经安装好
[hadoop@spark01-61cdh spark-1.6.1-bin-2.5.0-cdh5.3.6]$ java -version
java version "1.7.0_67"
Java(TM) SE Runtime Environment (build 1.7.0_67-b01)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)
检查Scala是否已经安装好
[hadoop@spark01-61cdh spark-1.6.1-bin-2.5.0-cdh5.3.6]$ scala -version
Scala code runner version 2.10.4 -- Copyright 2002-2013, LAMP/EPFL
3、 配置spark-env.sh

从模板复制一个配置文件

[hadoop@spark01-61cdh spark-1.6.1-bin-2.5.0-cdh5.3.6]$ cp conf/spark-env.sh.template conf/spark-env.sh

在spark-env.sh添加配置:

JAVA_HOME=/opt/modules/jdk1.7.0_67
SCALA_HOME=/opt/modules/scala-2.10.4/bin
HADOOP_CONF_DIR=/opt/modules/hadoop-2.5.0-cdh5.3.6/etc/hadoop
4、 启动Spark

[hadoop@spark01-61cdh spark-1.6.1-bin-2.5.0-cdh5.3.6]$ bin/spark-shell
这样就进入到了Spark的shell交互式命令行。
这里请注意,在启动时的日志里有一句:
16/10/12 23:40:36 INFO repl.SparkILoop: Created spark context..
Spark context available as sc.
这里意思是spark会创建一个context对象叫做sc。这个sc是SparkContext,它是SparkCore的程序入口,SparkContext会创建一个RDD。

5、 Web页面

启动shell后,可用通过4040端口的Web页面查看监控页面。

这里写图片描述

五、 Spark Shell使用

1、 准备数据

将spark根目录下的README.md文件上传到HDFS上去
[hadoop@spark01-61cdh spark-1.6.1-bin-2.5.0-cdh5.3.6]$ hdfs dfs -put README.md /

2、 测试

加载文件到rdd:scala> val rdd=sc.textFile(“/README.md”)
计算多少行:scala> rdd.count
计算包含Spark关键字的行数:scala> rdd.filter(line=>line.contains(“Spark”)).count
取前5行数据:scala> rdd.take(5)

六、 运行WordCount Demo

按照大数据处理三步走:

1、 读取数据
scala> val rdd=sc.textFile("/input.txt")

这个sc是一个SparkContext对象,textFile方法是读取HDFS上的文件,读取文件后,赋值给一个RDD对象。后续的操作都是用户RDD来操作的。

2、 处理数据

● scala> var wordcountRdd=rdd.flatMap(line => line.split(” “)).map(word =>(word,1)).reduceByKey((a,b)=>(a+b))
flatMap是将文件中的内容根据空格分隔开后,变换为一个单词数组。
map是针对每一个单词生成一个键值对,键为单词,值为1。
reduceByKey是将每一个键值对的值根据key进行合并相加,来统计各个单词的个数。
● scala> wordcountRdd.count
● scala> wordcountRdd.take(11)
res4: Array[(String, Int)] = Array((min,1), (hive,2), (word,1), (hua,2), (hello,1), (zhongh,1), (spark,2), (hadoop,2), (ren,2), (work,1), (storm,1))

3、 保存数据
scala> wordcountRdd.saveAsTextFile("/spark-out")  

保存到HDFS根目录下的spark-out目录下

七、 Spark TopKey Demo

//1、加载数据
scala> val rdd=sc.textFile("/input.txt")

//2、处理数据
scala> var wordcountRdd=rdd.flatMap(line => line.split(" ")).map(word =>(word,1)).reduceByKey((a,b)=>(a+b))

//3、根据个数排序后,取前5个
scala> wordcountRdd.map(tuple=>(tuple._2,tuple._1)).sortByKey(false).map(tuple=>(tuple._2,tuple._1)).take(5)

//链式编程:
sc.textFile("/input.txt"). flatMap(line => line.split(" ")).map(word =>(word,1)).reduceByKey((a,b)=>(a+b)). map(tuple=>(tuple._2,tuple._1)).sortByKey(false).map(tuple=>(tuple._2,tuple._1)).take(5)

八、 IDEA开发Spark应用案例

1、 配置Windows环境变量

下载winutils的windows版本,下载地址是:https://github.com/srccodes/hadoop-common-2.2.0-bin,解压到F:\windowshadoop。
设置Windows的系统环境变量:
HADOOP_HOME=F:\windowshadoop\hadoop-common-2.2.0-bin
path环境变量添加一个 $HADOOP_HOME\bin
因为在Spark程序在Windows上运行的时候会查找HADOOP_HOME环境变量,并查找目录下的winutils.exe文件,所以要保证HADOOP_HOME下的winutils.exe可以访问到。

2、 IDEA创建一个Scala项目

创建一个Scala项目,Project name为SparkProject,
这里写图片描述

3、 创建目录

在Project Structure的Modeles中添加如下目录结构,并将main目录设置为Source类型,将resources目录设置为Resources类型。

这里写图片描述

4、 复制配置文件

将运行时连接的Hadoop集群中的core-site.xml和hdfs-site.xml复制到resources目录下。

这里写图片描述

这两个配置文件保证了Spark程序可以正确地访问到hadoop集群。

5、 添加spark jar包Lib

在Project Structure中的Libraries中添加jar包,将spark的五个jar包添加进来,这个五个jar包可以在spark的lib目录下找到。

这里写图片描述

6、 编码

在main目录下添加WordCount Scala Object文件。
这里写图片描述

代码如下:

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

/**
  * Created by 鸣宇淳 on 2017/10/18.
  */
object WordCount {
  def main(args: Array[String]) {

    //设置运行账号为hadoop,跟Hadoop的账号一致
    System.setProperty("HADOOP_USER_NAME", "hadoop");
    //创建一个SparkConf
    val sparkConf = new SparkConf()
      //设置应用的名称,会在WEB监控页面中显示
      .setAppName("WordCountSparkApp")
      //设置spark运行在本地
      //.setMaster("spark://spark01-61cdh.chybinmy.com:7077")
      //.setMaster("local")
      .setMaster(args(0))

    //创建一个SparkContext
    val sc = new SparkContext(sparkConf)

    /** ========================================================*/
    //第一步,读取数据
    //从HDFS上读取数据
    val rdd = sc.textFile(args(1))

    //第二步:处理数据
    val wordCountRdd = rdd
      //根据空格分隔符分割每行的单词,形成一个数组
      .flatMap(line => line.split(" "))
      //每个单词生成一个二元组对,键为单词,值为1
      .map(word => (word, 1))
      //根据Key合并计算数量,得出各个单词的个数
      .reduceByKey(_ + _)

    //第三步:输出数据
    //wordCountRdd.foreach(tuple => println(tuple))
    wordCountRdd.saveAsTextFile(args(2))

    /** ========================================================*/

    //停止sparkContext
    sc.stop()
  }
}
7、 准备测试数据

在HDFS上新建一个文件,内容如下:

[hadoop@bigdata-51cdh hadoop-2.5.0-cdh5.3.6]$ hdfs dfs -cat /input.txt
hadoop spark hello word
work storm hive
zhongh hadoop ren min 
hadoop spark hive
ren hive hua hadoop
8、 调试运行

在IDEA中调试运行。

9、 查看结果
[hadoop@bigdata-51cdh hadoop-2.5.0-cdh5.3.6]$ hdfs dfs -cat /out1018/part-00000
(min,1)
(spark,2)
(hive,3)
(hadoop,4)
(ren,2)
(work,1)
(word,1)
(hua,1)
(hello,1)
(zhongh,1)
(storm,1)
10、 打包

(1) 添加Artifacts

Project Structure中的Artifacts下添加jar,选择main函数所在类。
这里写图片描述

(2) 删除spark相关的jar包
因为用户代码打的jar包里不能有Hadoop、Spark相关的jar包,因为会在执行时自动添加,所以要将其他引用删除。

这里写图片描述

(3) 打包

在Build菜单里选择Build Artifact,然后选择Build,开始打包,打包后如下:
这里写图片描述

11、 运行jar包

在Spark所在目录执行spark-submit命令:
[hadoop@spark01-61cdh spark-1.6.1-bin-2.5.0-cdh5.3.6]$ bin/spark-submit SparkProject.jar “local” “/input.txt” “/out1019” –class WordCount

(4) 查看HDFS上的输出文件

[hadoop@bigdata-51cdh hadoop-2.5.0-cdh5.3.6]$ hdfs dfs -cat /out1019/part-00000
(min,1)
(spark,2)
(hive,3)
(hadoop,4)
(ren,2)
(work,1)
(word,1)
(hua,1)
(hello,1)
(zhongh,1)
(storm,1)

可以看到,已经完成对单词的统计


这一篇博文是【大数据技术●降龙十八掌】系列文章的其中一篇,点击查看目录:这里写图片描述大数据技术●降龙十八掌

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值