1.Spark 基础解析之概述及集群安装

1 Spark 概述

1.1 什么是Spark?

官网:http://spark.apache.org
1.Spark 基础解析之概述及集群安装_第1张图片
1.Spark 基础解析之概述及集群安装_第2张图片
        Spark是一种快速、通用、可扩展的大数据分析引擎,2014年2月成为Apache顶级项目,由Scala语言编写

        目前,Spark生态系统已经发展成为一个包含多个子项目的集合,其中包含SparkSQL、Spark Streaming、GraphX、MLib、SparkR等子项目,Spark是基于内存计算的大数据并行计算框架。除了扩展了广泛使用的 MapReduce 计算模型,而且高效地支持更多计算模式,包括交互式查询和流处理。Spark 适用于各种各样原先需要多种不同的分布式平台的场景,包括批处理、迭代算法、交互式查询、流处理。通过在一个统一的框架下支持这些不同的计算,Spark 使我们可以简单而低耗地把各种处理流程整合在一起。而这样的组合,在实际的数据分析 过程中是很有意义的。不仅如此,Spark 的这种特性还大大减轻了原先需要对各种平台分 别管理的负担

        大一统的软件栈,各个组件关系密切并且可以相互调用,这种设计有几个好处:1、软件栈中所有的程序库和高级组件 都可以从下层的改进中获益。2、运行整个软件栈的代价变小了。不需要运 行 5 到 10 套独立的软件系统了,一个机构只需要运行一套软件系统即可。系统的部署、维护、测试、支持等大大缩减。3、能够构建出无缝整合不同处理模型的应用

Spark 内置项目如下:
1.Spark 基础解析之概述及集群安装_第3张图片
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得到了众多大数据公司的支持,这些公司包括Hortonworks、IBM、Intel、Cloudera、MapR、Pivotal、百度、阿里、腾讯、京东、携程、优酷土豆。当前百度的Spark已应用于凤巢、大搜索、直达号、百度大数据等业务;阿里利用GraphX构建了大规模的图计算和图挖掘系统,实现了很多生产系统的推荐算法;腾讯Spark集群达到8000台的规模,是当前已知的世界上最大的Spark集群。

1.2 Spark 特点

        
        与Hadoop的MapReduce相比,Spark基于内存的运算要快100倍以上,基于硬盘的运算也要快10倍 以上。Spark实现了高效的DAG执行引擎,可以通过基于内存来高效处理数据流。计算的中间结果是存在于内存中的
1.Spark 基础解析之概述及集群安装_第4张图片
        易用
        Spark支持Java、Python和Scala的API,还支持超过80种高级算法,使用户可以快速构建不同的应用。而且Spark支持交互式的Python和Scala的shell,可以非常方便地在这些shell中使用Spark集群来验证解决问题的方法
1.Spark 基础解析之概述及集群安装_第5张图片
        通用
        Spark提供了统一的解决方案。Spark可以用于批处理、交互式查询(Spark SQL)、实时流处理(Spark Streaming)、机器学习(Spark MLlib)和图计算(GraphX)。这些不同类型的处理都可以在同一个应用中无缝使用。Spark统一的解决方案非常具有吸引力,毕竟任何公司都想用统一的平台去处理遇到的问题,减少开发和维护的人力成本和部署平台的物力成本

        兼容性
        Spark可以非常方便地与其他的开源产品进行融合。比如,Spark可以使用Hadoop的YARN和Apache Mesos作为它的资源管理和调度器,器,并且可以处理所有Hadoop支持的数据,包括HDFS、HBase和Cassandra等。这对于已经部署Hadoop集群的用户特别重要,因为不需要做任何数据迁移就可以使用Spark的强大处理能力。Spark也可以不依赖于第三方的资源管理和调度器,它实现了Standalone作为其内置的资源管理和调度框架,这样进一步降低了Spark的使用门槛,使得所有人都可以非常容易地部署和使用Spark。此外,Spark还提供了在EC2上部署Standalone的Spark集群的工具
1.Spark 基础解析之概述及集群安装_第6张图片

1.3 Spark 的用户和用途

        我们大致把Spark的用例分为两类:数据科学应用和数据处理应用。也就对应的有两种人群:数据科学家和工程师

        数据科学任务
        主要是数据分析领域,数据科学家要负责分析数据并建模,具备 SQL、统计、预测建模(机器学习)等方面的经验,以及一定的使用 Python、 Matlab 或 R 语言进行编程的能力

        数据处理应用
        工程师定义为使用 Spark 开发 生产环境中的数据处理应用的软件开发者,通过对接Spark的API实现对处理的处理和转换等任务

1.4 Spark 核心概念

1.Spark 基础解析之概述及集群安装_第7张图片
Application:基于Spark 的应用程序,包含了driver程序和集群上的executor
Driver Program:运行main函数并且新建 SparkContext 的程序
Executor:是在一个Worker Node 上为某应用启动的一个进程,该进程负责运行任务,并且负责将数据存在内存或磁盘上。每个应用都有各自独立的executors
Cluster Manager:在集群上获取资源的外部服务(例如:Standalone、Mesos、Yarn)
Worker Node:集群中任何可以运行应用的节点
Task:被送到某个executor上的工作单元
Job:包含很多任务的并行计算,可以看作和Spark的Action对应
Stage:一个Job会被拆分成很多组任务,每组任务被称为Stage(就像MapReduce分map任务和reduce任务一样)

2 Spark 集群安装

        Spark集群有三种部署模式,最主要资源管理方式也有三种,依次排名为为Hadoop Yarn, Apache Standalone 和Mesos。在单机使用时,Spark还可以采用最基本的local模式。

        目前Apache Spark支持三种分布式部署方式,分别是standalone、spark on mesos和 spark on YARN,其中,第一种类似于MapReduce 1.0所采用的模式,内部实现了容错性和资源管理,后两种则是未来发展的趋势,部分容错性和资源管理交由统一的资源管理系统完成:让Spark运行在一个通用的资源管理系统之上,这样可以与其他计算框架,比如MapReduce,公用一个集群资源,最大的好处是降低运维成本和提高资源利用率(资源按需分配)

        实际学习中使用两台节点安装Spark 集群分布式或者单节点spark on yarn 就可以,下述笔者会介绍如何安装

2.1 Spark 集群分布式安装

        笔者在安装Spark时,准备了两台虚拟机(一主一从),里面安装好了centos7系统、做了初始化配置:静态IP设置、主机名及IP映射、SSH无密码登录、安装JDK1.8,Spark集群规划如下

IP 主机名 作用 软件 进程
192.168.242.150 Master 主节点 JDK1.8、Scala2.12.3、Spark2.2.0 Master
192.168.242.151 Slave 子节点 JDK1.8、Scala2.12.3、Spark2.2.0 Worker

注意:这种安装只有一个Master,那就是Master节点存在单点故障,要解决此问题,就要借助zookeeper,并且启动至少两个Master节点来实现高可靠,配置也相对简单,请自行查询资料。

  • 安装scala
    官网:http://www.scala-lang.org/
    下载scala,解压并移动到指定目录
$ wget https://downloads.lightbend.com/scala/2.12.3/scala-2.12.3.tgz
$ tar -zxvf scala-2.12.3.tgz
$ sudo mv scala-2.12.3 /opt/scala
  • 安装spark
    1.Spark 基础解析之概述及集群安装_第8张图片
    下载spark,解压并移动到指定目录
$ wget https://d3kbcqa49mib13.cloudfront.net/spark-2.2.0-bin-hadoop2.7.tgz
$ tar -zxvf spark-2.2.0-bin-hadoop2.7.tgz
$ sudo mv spark-2.2.0-bin-hadoop2.7 /opt/spark
  • 配置环境变量
# Java Environment Variable
export JAVA_HOME=/usr/java/jdk1.8.0_131
export PATH=$PATH:$JAVA_HOME/bin

# Scala Environment Variable
export SCALA_HOME=/opt/scala
export PATH=$PATH:$SCALA_HOME/bin

# Spark Environment Variable
export SPARK_HOME=/opt/spark
export PATH=$PATH:$SPARK_HOME/bin:$SPARK_HOME/sbin

验证环境变量是否设置成功

$ java -version
$ scala -version
  • 修改配置文件
    进入spark的安装目录下的conf目录中,拷贝spark-env.sh.template文件并重命名为spark-env.sh
$ cd /opt/spark/conf/
$ cp spark-env.sh.template spark-env.sh

在该配置文件的末尾,添加如下配置

export JAVA_HOME=/usr/java/jdk1.8.0_131
export SPARK_MASTER_IP=Master
export SPARK_MASTER_PORT=7077

拷贝slaves.template文件并重命名为slaves,在该文件中添加子节点所在的位置(Worker节点)
该文件中默认为localhost,表示伪分布式,即本机既是Master,又时Slave,删除localhost,依次添加子节点,每行一个。笔者只有一台slave,dn1

配置完成后,将配置好的Spark及Scala拷贝到其他节点上

scp -r /opt/scala/ dn1:/opt/scala
scp -r /opt/spark/ dn1:/opt/spark
  • 启动Spark
    Spark 集群配置完毕,目前是1个Master,1个Work,在Master上启动Spark集群
[hadoop@Master ~]$ cd /opt/spark/sbin/
[hadoop@Master sbin]$ ./start-all.sh 
starting org.apache.spark.deploy.master.Master, logging to /opt/spark/logs/spark-hadoop-org.apache.spark.deploy.master.Master-1-Master.out
dn1: starting org.apache.spark.deploy.worker.Worker, logging to /opt/spark/logs/spark-hadoop-org.apache.spark.deploy.worker.Worker-1-dn1.out

启动成功后执行jps命令,主节点上有Master进程,子节点上有Worker进程

[hadoop@Master sbin]$ jps
3737 Jps
3675 Master

[hadoop@dn1 ~]$ jps
5283 Worker
5311 Jps

查看进程
7077:spark默认运行的端口
8080:spark 管理界面访问端口

[hadoop@Master sbin]$ ps -ef | grep java
hadoop     3675      1  2 10:06 pts/0    00:00:15 /usr/java/jdk1.8.0_131/bin/java -cp /opt/spark/conf/:/opt/spark/jars/* -Xmx1g org.apache.spark.deploy.master.Master --host Master --port 7077 --webui-port 8080
hadoop     3748   2742  0 10:15 pts/0    00:00:00 grep --color=auto java

登录Spark管理界面查看集群状态,访问:http://master:8080/
1.Spark 基础解析之概述及集群安装_第9张图片

2.2 Spark on YARN 伪分布式

  • 安装Spark

下载解压重命名

$ wget http://mirrors.tuna.tsinghua.edu.cn/apache/spark/spark-2.2.1/spark-2.2.1-bin-hadoop2.7.tgz
$ tar -zxvf spark-2.2.1-bin-hadoop2.7.tgz
$ mv spark-2.2.1-bin-hadoop2.7 spark

配置Spark

$ cd spark/conf/
$ cp spark-env.sh.template spark-env.sh
$ vim spark-env.sh
export JAVA_HOME=/home/hadoop/software/jdk
export SCALA_HOME=/home/hadoop/software/scala
export HADOOP_HOME=/home/hadoop/software/hadoop
export HADOOP_CONF_DIR=/home/hadoop/software/hadoop/etc/hadoop
export SPARK_MASTER_IP=harvey
export SPARK_MASTER_PORT=7077

slaves文件配置slave节点,该文件中默认为localhost,表示伪分布式,即本机既是Master,又时Slave

$ cp slaves.template slaves

注意:
        (1).不用启动spark的master和slaves服务,因为是靠yarn进行任务调度,所以直接提交任务即可
        (2).如果启动Spark的master和worker服务,这是Spark的standalone运行模式,不是Spark on YARN运行模式

  • spark-shell运行在YARN上
    先启动hadoop
$ start-all.sh

jps查看进程

5428 NameNode
6148 NodeManager
6005 ResourceManager
5752 SecondaryNameNode
5545 DataNode
6525 Jps

spark-shell运行在YARN上,执行如下命令

$ /home/hadoop/software/spark/bin./spark-shell --master yarn --deploy-mode client

创建RDD

scala> val rdd=sc.parallelize(1 to 100,5)
rdd: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[0] at parallelize at :24

scala> rdd.count
res0: Long = 100  
  • 问题记录

问题描述:执行命令./spark-shell --master yarn --deploy-mode client spark-shell运作在YARN上报错
错误信息如下

java.io.IOException: Failed to send RPC 8555495584463695736 to /192.168.191.65:59952: java.nio.channels.ClosedChannelException
	at org.apache.spark.network.client.TransportClient.lambda$sendRpc$2(TransportClient.java:237)
	at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:507)
	at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:481)
	at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:420)
	at io.netty.util.concurrent.DefaultPromise.tryFailure(DefaultPromise.java:122)
	at io.netty.channel.AbstractChannel$AbstractUnsafe.safeSetFailure(AbstractChannel.java:852)
	at io.netty.channel.AbstractChannel$AbstractUnsafe.write(AbstractChannel.java:738)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.write(DefaultChannelPipeline.java:1251)
	at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:733)
	at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:725)
	at io.netty.channel.AbstractChannelHandlerContext.access$1900(AbstractChannelHandlerContext.java:35)
	at io.netty.channel.AbstractChannelHandlerContext$AbstractWriteTask.write(AbstractChannelHandlerContext.java:1062)
	at io.netty.channel.AbstractChannelHandlerContext$WriteAndFlushTask.write(AbstractChannelHandlerContext.java:1116)
	at io.netty.channel.AbstractChannelHandlerContext$AbstractWriteTask.run(AbstractChannelHandlerContext.java:1051)
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:399)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:446)
	at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:131)
	at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.nio.channels.ClosedChannelException
	at io.netty.channel.AbstractChannel$AbstractUnsafe.write(...)(Unknown Source)
2018-05-31 17:39:49,222 ERROR util.Utils: Uncaught exception in thread Yarn application state monitor
org.apache.spark.SparkException: Exception thrown in awaitResult: 
	at org.apache.spark.util.ThreadUtils$.awaitResult(ThreadUtils.scala:205)
	at org.apache.spark.rpc.RpcTimeout.awaitResult(RpcTimeout.scala:75)
	at org.apache.spark.scheduler.cluster.CoarseGrainedSchedulerBackend.requestTotalExecutors(CoarseGrainedSchedulerBackend.scala:551)
	at org.apache.spark.scheduler.cluster.YarnSchedulerBackend.stop(YarnSchedulerBackend.scala:97)
	at org.apache.spark.scheduler.cluster.YarnClientSchedulerBackend.stop(YarnClientSchedulerBackend.scala:151)
	at org.apache.spark.scheduler.TaskSchedulerImpl.stop(TaskSchedulerImpl.scala:517)
	at org.apache.spark.scheduler.DAGScheduler.stop(DAGScheduler.scala:1670)
	at org.apache.spark.SparkContext$$anonfun$stop$8.apply$mcV$sp(SparkContext.scala:1928)
	at org.apache.spark.util.Utils$.tryLogNonFatalError(Utils.scala:1317)
	at org.apache.spark.SparkContext.stop(SparkContext.scala:1927)
	at org.apache.spark.scheduler.cluster.YarnClientSchedulerBackend$MonitorThread.run(YarnClientSchedulerBackend.scala:108)
Caused by: java.io.IOException: Failed to send RPC 8555495584463695736 to /192.168.191.65:59952: java.nio.channels.ClosedChannelException
	at org.apache.spark.network.client.TransportClient.lambda$sendRpc$2(TransportClient.java:237)
	at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:507)
	at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:481)
	at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:420)
	at io.netty.util.concurrent.DefaultPromise.tryFailure(DefaultPromise.java:122)
	at io.netty.channel.AbstractChannel$AbstractUnsafe.safeSetFailure(AbstractChannel.java:852)
	at io.netty.channel.AbstractChannel$AbstractUnsafe.write(AbstractChannel.java:738)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.write(DefaultChannelPipeline.java:1251)
	at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:733)
	at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:725)
	at io.netty.channel.AbstractChannelHandlerContext.access$1900(AbstractChannelHandlerContext.java:35)
	at io.netty.channel.AbstractChannelHandlerContext$AbstractWriteTask.write(AbstractChannelHandlerContext.java:1062)
	at io.netty.channel.AbstractChannelHandlerContext$WriteAndFlushTask.write(AbstractChannelHandlerContext.java:1116)
	at io.netty.channel.AbstractChannelHandlerContext$AbstractWriteTask.run(AbstractChannelHandlerContext.java:1051)
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:399)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:446)
	at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:131)
	at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.nio.channels.ClosedChannelException
	at io.netty.channel.AbstractChannel$AbstractUnsafe.write(...)(Unknown Source)
Welcome to
      ____              __
     / __/__  ___ _____/ /__
    _\ \/ _ \/ _ `/ __/  '_/
   /___/ .__/\_,_/_/ /_/\_\   version 2.2.1
      /_/
         
Using Scala version 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_161)
Type in expressions to have them evaluated.
Type :help for more information.

scala>

解决方法:在 yarn-site.xml 中添加如下配置,重启hadoop


	yarn.nodemanager.pmem-check-enabled
	false



	yarn.nodemanager.vmem-check-enabled
	false

你可能感兴趣的