Day66_Spark(一)Spark基础核心知识

SparkCore课堂讲义

第一讲 Spark基础核心知识

课程大纲

课程内容

学习效果

掌握目标

Spark简介

大数据生态发展

了解

什么是Spvark

Spark开发环境

Spark standalone

掌握

Spark HA

掌握

Spark核心概念

Spark核心概念

掌握

Spark编程体验

Spark项目创建

掌握

Spark项目编码

掌握

一、什么是Spark

(一)大数据生态

(二)什么是Spark

1、Spark特点

快的原因:

1. 基于内存计算

2. 计算和数据的分离

3. 基于DAGScheduler的计算划分

4. 只有一次的Shuffle输出操作

Ease of Use:

Spark提供超过80多个高阶算子函数,来支持对数据集的各种各样的计算,使用的时候,可以使用java、scala、python、R,非常灵活易用。

df = spark.read.json("logs.json") 
df.where("age > 21")
	.select("name.first")
    .show()

Generality:

通用性如下图1-3所示:

Runs Everywhere:
    Spark程序可以再多个平台上面运行,如下图1-4所示:


2、Spark概述总结

什么是Spark呢?它就是一个集成离线计算,实时计算,SQL查询,机器学习,图计算为一体的通用的计算框架。

何为通用?就是在一个项目中,既可以使用离线计算,也可以使用其他比如,SQL查询,机器学习,图计算等等,而这是Spark最最最强大的优势,没有之一。

而这一切的基础是SparkCore,速度比传统的mr快的原因就是基于内存的计算。

Spark开发过程中,使用到的模型——RDD(Resilient Distributed Dataset, 弹性式分布式数据集),在编程中起到了非常重要的作用。

3、RDD概述

何为RDD?其实RDD就是一个不可变的scala的并行集合。

Spark的核心概念就是RDD,指的是一个不可变、可分区、里面元素可并行计算的集合,这个数据的全部或者部分可以缓存在内存中,在多次计算间被重用。

RDD在抽象来说是一种元素集合,包含了数据。他是被分区的,分为多个分区,每个分区分布在集群中的不同worker节点上面,从而让RDD中的数据可以被并行操作。

RDD通常通过Hadoop上的文件,即HDFS文件或者Hive表来进行创建;也可以通过RDD的本地创建转换而来。

传统的MapReduce虽然具有自动容错、平衡负载和可拓展性的优点,但是其最大缺点是采用非循环式的数据流模型,使得在迭代计算式要进行大量的磁盘IO操作。RDD正式解决这个缺点的抽象方法。

RDD最重要的特性就是,提供了容错性,可以自动从节点失败中恢复过来。即如果某个节点上的RDD Partition,因为节点故障,导致数据丢失,那么RDD会自动通过自己的数据来源重新计算该Partition。这一切对使用者是透明的,这一切的背后工作都是通过RDD的lineage特性来实现的。

RDD的数据默认情况下是存放在内存中的,但是内存资源不足的时候,Spark会自动将RDD数据溢出到磁盘(弹性)。

4、RDD特性

通过上述的描述,我们可以从以下几个方面来描述RDD

(一)弹性

如果内存充足,那集合数据的存储和计算,就都在内存中完成;如果内存不足,需要有一部分数据溢出到磁盘,然后在磁盘完成存储和计算。

(二)分布式

就和之前学习的分布式概念一样,一个集合的数据被拆分成多个部分,这每一个部分被称之为一个分区partition,还是一个scala的不可变的集合。默认情况下,partition是和hdfs中data-block块对应的,spark加载hdfs文件时,一个data-block块对应一个partition。

所以,对RDD的操作,本质上是对着每一个RDD对应分区partition的操作。

(三)数据集

存放数据的集合

 而Spark就是对这个RDD及其集合功能算子的实现。

 RDD,弹性式分布式数据集,是Spark的第一代编程模型。

 说白了RDD就是一个抽象数据类型。

(四)RDD之间是存在依赖关系的

这些RDD之间的依赖关系,就形成了一个RDD的有向无环图DAG,依赖关系称之为RDD血缘关系或者血统,因为lineage。

依赖关系呢,分为了两种:窄依赖和宽依赖。具体我们会在spark stage阶段划分的时候进行具体说明。

(五)移动计算优于移动数据

partition提供的最佳计算位置,利于数据处理的本地化即计算向数据移动而不是移动数据。

总结如下图1-5所示:

  1. 一组分片(Partition),即数据集的基本组成单位。对于RDD来说,每个分片都会被一个计算任务处理,并决定并行计算的粒度。用户可以在创建RDD时指定RDD的分片个数,如果没有指定,那么就会采用默认值。默认值就是程序所分配到的CPU Core的数目。
  2. 一个计算每个分区的函数。Spark中RDD的计算是以分片为单位的,每个RDD都会实现compute函数以达到这个目的。compute函数会对迭代器进行复合,不需要保存每次计算的结果。
  3. RDD之间的依赖关系。RDD的每次转换都会生成一个新的RDD,所以RDD之间就会形成类似于流水线一样的前后依赖关系。在部分分区数据丢失时,Spark可以通过这个依赖关系重新计算丢失的分区数据,而不是对RDD的所有分区进行重新计算。
  4. 一个Partitioner,即RDD的分片函数。当前Spark中实现了两种类型的分片函数,一个是基于哈希的HashPartitioner,另外一个是基于范围的RangePartitioner。只有对于key-value的RDD,才会有Partitioner,非key-value的RDD的Parititioner的值是None。Partitioner函数不但决定了RDD本身的分片数量,也决定了parent RDD Shuffle输出时的分片数量。
  5. 一个列表,存储存取每个Partition的对应数据的优先位置(preferred location)。对于一个HDFS文件来说,这个列表保存的就是每个Partition所在的块的位置。按照“移动数据不如移动计算”的理念,Spark在进行任务调度的时候,会尽可能地将计算任务分配到其所要处理数据块的存储位置。

5、RDD在Spark中的地位和作用

(一)为什么会有Spark

因为传统的并行计算模型无法有效的进行交互式计算;而Spark的使命便是解决这个问题,这也是它存在的价值和理由。

(二)Spark如何解决迭代计算

其主要实现思想就是RDD,把所有计算的数据保存在分布式的内存中。迭代计算通常情况下都是对同一个数据集做反复的迭代计算,数据在内存中将大大降低IO操作。这也是Spark设计的核心:内存计算

(三)Spark如何实现交互式计算

因为Spark是用scala语言实现的,Spark和scala能够紧密的集成。所以Spark可以完美的运用scala的解释器,使得其中的scala可以向操作本地集合对象一样轻松的操作分布式数据集。

(四)Spark和RDD的关系

可以理解为:RDD是一种具有容错性,基于内存的集群计算抽象方法,Spark则是这个抽象方法的实现。

二、Spark分布式环境安装

当前大纲中使用的Spark的版本是2.4.7,最新的版本应该3.0.1。

下载地址:https://archive.apache.org/dist/spark/spark-2.4.7/

提供的安装包:

spark-2.4.7.tgz ---->源码包

spark-2.4.7-bin-hadoop2.7.tgz ---->安装包

(一)基于Windows的环境体验

1、解压

2、启动%SPARK_HOME%\bin\spark-shell.cmd脚本

启动界面如下图1-7所示、

3、执行入门案例

(1)spark-shell终端代码:

scala> sc.textFile("E:/data/hello.txt")
.flatMap(_.split("\\s+"))
.map((_, 1))
.reduceByKey(_+_)
.foreach(println)

 (2)结果查看

(3)Web-UI

能够得出的基本结论是什么?

  1. Spark的application,可以有非常多的job作业,和mr不同,一个应用就提交一个job就行。
  2. job的执行,需要action算子操作触发,否则不会执行,触发的操作就是spark作业执行的动因。
  3. spark job作业的执行是分stage阶段的

spark job作业的执行stage阶段形成了一个stage的DAG有向无环图

 (二)Spark分布式环境安装

1、解压

[root@node01 ~]$ tar -zxvf spark-2.4.7-bin-hadoop2.7.tgz -C /export/servers/

2、重命名

[root@node01 ~]$ mv spark-2.4.7-bin-hadoop2.7/ spark

3、添加环境变量

vim /etc/profile

export SPARK_HOME=/export/servers/spark
export PATH=$PATH:$SPARK_HOME/bin:$SPARK_HOME/sbin

4、环境变量生效

[root@node01 ~]$ source /etc/profile

5、修改配置文件

(1)$SPARK_HOME/conf/slaves

a)、拷贝slaves和spark-env.conf文件

[root@node01 conf]# mv slaves.template slaves
[root@node01 conf]# mv spark-env.sh.template spark-env.sh

b)、修改slaves文件内容

node02
node03

(2)$SPARK_HOME/conf/spark-env.sh

a)添加如下内容:

export JAVA_HOME=/export/servers/jdk1.8.0_141
export SPARK_MASTER_HOST=node01
export SPARK_MASTER_PORT=7077 

b)发送spark到其它节点中

scp -r spark/ node02:$PWD
scp -r spark/ node03:$PWD

6、启动并体验

(1)启动

    使用$SPARK_HOME/sbin目录下的脚本start-all.sh

(2)停止

使用$SPARK_HOME/sbin目录下的脚本stop-all.sh

stop-all.sh

(3)验证

启动起来之后,spark的主节点master会类似resourcemanager提供一个web的ui,访问地址为:http://master-ip:8080

sbin/start-all.sh
sbin/stop-all.sh

 (4)提交任务&执行程序

[root@node01 spark]# bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master spark://node01:7077 \
--driver-memory 1g \
--executor-memory 1g \
--executor-cores 2 \
--queue default \
./examples/jars/spark-examples_2.11-2.4.7.jar \
100

(三)Spark分布式HA环境安装

因为在目前情况下,集群中只有一个Master,如果master挂掉,便无法对外提供新的服务,显然有单点故障问题,解决方法就是master的ha。

有两种方式解决单点故障,一种基于文件系统FileSystem(生产中不用),还有一种基于Zookeeper(使用)

配置基于Zookeeper的一个ha是非常简单的,只需要在spark-env.sh中添加一句话即可。

注释掉如下内容:
#SPARK_MASTER_HOST=node01
export SPARK_MASTER_PORT=7077
添加上如下内容:配置的时候保证下面语句在一行,否则配置不成功,每个-D参数使用空格分开
export SPARK_DAEMON_JAVA_OPTS="
-Dspark.deploy.recoveryMode=ZOOKEEPER 
-Dspark.deploy.zookeeper.url=node01:2181,node02:2181,node03:2181
-Dspark.deploy.zookeeper.dir=/spark"
  1. spark.deploy.recoveryMode设置成 ZOOKEEPER
  2. spark.deploy.zookeeper.urlZooKeeper URL
  3. spark.deploy.zookeeper.dir ZooKeeper 保存恢复状态的目录,缺省为 /spark

因为ha不确定master在node01上面启动,所以将

export SPARK_MASTER_HOST=node01注释掉

[root@node01 conf]# scp -r spark-env.sh node02:$PWD

[root@node01 conf]# scp -r spark-env.sh node03:$PWD

最后别忘了,同步spark-env.sh到其它机器。

同步完毕之后,重启spark集群!

node01的master状态

node02也启动master

start-master.sh,其状态为:

(1)提交任务&执行程序

[root@node01 spark]# bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master spark://node01:7077,node02:7077 \
--driver-memory 1g \
--executor-memory 1g \
--executor-cores 2 \
--queue default \
./examples/jars/spark-examples_2.11-2.4.7.jar \
100

ha验证,要干掉alive的master,观察standby的master

node02的状态缓慢的有standby转变为alive

(四)动态增删worker节点

1、上线

不需要在现有集群的配置上做任何修改,只需要准备一台worker机器即可,可和之前的worker的配置相同。

spark]# sbin/start-slave.sh node01:7077 -c 4 -m 1024M

2、下线

(五)Spark分布式Yarn环境安装

1)修改hadoop配置文件yarn-site.xml,添加如下内容:

[root@node01 hadoop]$ vi 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>

2)修改spark-env.sh,添加如下配置:

[root@node01 conf]# vi spark-env.sh
YARN_CONF_DIR=/export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop
HADOOP_CONF_DIR=/export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop

3)client模式

[root@node01 spark]# bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode client \
./examples/jars/spark-examples_2.11-2.4.7.jar \
100

注意:在提交任务之前需启动HDFS以及YARN集群。

4)cluster模式

[root@node01 spark]# bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode cluster \
./examples/jars/spark-examples_2.11-2.4.7.jar \
100

三、Spark核心概念

(一)、名词解释

  1. ClusterManager:在Standalone(上述安装的模式,也就是依托于spark集群本身)模式中即为Master(主节点),控制整个集群,监控Worker。在YARN模式中为资源管理器ResourceManager(国内spark主要基于yarn集群运行,欧美主要基于mesos来运行)。
  2. Application:Spark的应用程序,包含一个Driver program和若干Executor。
  3. SparkContext:Spark应用程序的入口,负责调度各个运算资源,协调各个Worker Node上的Executor。
  4. Worker:从节点,负责控制计算节点,启动Executor。在YARN模式中为NodeManager,负责计算节点的控制,启动的进程叫Container。
  5. Driver:运行Application的main()函数并创建SparkContext(是spark中最重要的一个概念,是spark编程的入口,作用相当于mr中的Job)。
  6. Executor:执行器,在worker node上执行任务的组件、用于启动线程池运行任务。每个Application拥有独立的一组Executors。
  7. SparkContext:整个应用的上下文,控制应用的生命周期,是spark编程的入口。
  8. RDD:Spark的基本计算单元,一组RDD可形成执行的有向无环图RDD Graph。

RDD是弹性式分布式数据集,理解从3个方面去说:弹性、数据集、分布式。

是Spark的第一代的编程模型。

  1. DAGScheduler:实现将Spark作业分解成一到多个Stage,每个Stage根据RDD的Partition个数决定Task的个数,然后生成相应的Task set放到TaskScheduler中。DAGScheduler就是Spark的大脑,中枢神经。
  2. TaskScheduler:将任务(Task)分发给Executor执行。
  3. Stage:一个Spark作业一般包含一到多个Stage。
  4. Task:一个Stage包含一到多个Task,通过多个Task实现并行运行的功能。task的个数由rdd的partition分区决定,spark是一个分布式计算程序,所以一个大的计算任务,就会被拆分成多个小的部分,同时进行计算。一个partition对应一个task任务。
  5. Transformations:转换(Transformations) (如:map, filter, groupBy, join等),Transformations操作是Lazy的,也就是说从一个RDD转换生成另一个RDD的操作不是马上执行,Spark在遇到Transformations操作时只会记录需要这样的操作,并不会去执行,需要等到有Actions操作的时候才会真正启动计算过程进行计算。
  6. Actions:操作/行动(Actions)算子 (如:count, collect, foreach等),Actions操作会返回结果或把RDD数据写到存储系统中。Actions是触发Spark启动计算的动因。
  7. SparkConf:负责存储配置信息。作用相当于hadoop中的Configuration。

(二)、Spark官网组件说明

官网组件说明如下图1-19所示:

Spark应用程序作为集群上的独立进程集运行,由主程序(称为驱动程序)中的SparkContext对象协调。

具体来说,要在集群上运行,SparkContext可以连接到几种类型的集群管理器(Spark自己的独立集群管理器、Mesos或YARN),这些管理器可以跨应用程序分配资源。一旦连接,Spark将获取集群中节点上的执行器,这些执行器是为应用程序运行计算和存储数据的进程。接下来,它将应用程序代码(由传递给SparkContext的JAR或Python文件定义)发送给执行器。最后,SparkContext将任务发送给执行器以运行。

四、Spark编程体验

(一)、Spark项目的创建

1、项目依赖管理

<properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <encoding>UTF-8</encoding>
        <scala.version>2.11.8</scala.version>
        <scala.compat.version>2.11</scala.compat.version>
        <hadoop.version>2.7.4</hadoop.version>
        <spark.version>2.2.0</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>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql_2.11</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-hive_2.11</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-hive-thriftserver_2.11</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-streaming_2.11</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <!-- <dependency>
             <groupId>org.apache.spark</groupId>
             <artifactId>spark-streaming-kafka-0-8_2.11</artifactId>
             <version>${spark.version}</version>
         </dependency>-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-streaming-kafka-0-10_2.11</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql-kafka-0-10_2.11</artifactId>
            <version>${spark.version}</version>
        </dependency>

        <!--<dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.6.0-mr1-cdh5.14.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-client</artifactId>
            <version>1.2.0-cdh5.14.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-server</artifactId>
            <version>1.2.0-cdh5.14.0</version>
        </dependency>-->

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.7.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-client</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-server</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>com.typesafe</groupId>
            <artifactId>config</artifactId>
            <version>1.3.3</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>
    </dependencies>

    <build>
        <sourceDirectory>src/main/scala</sourceDirectory>
        <testSourceDirectory>src/test/scala</testSourceDirectory>
        <plugins>
            <!-- 指定编译java的插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
            </plugin>
            <!-- 指定编译scala的插件 -->
            <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-surefire-plugin</artifactId>
                <version>2.18.1</version>
                <configuration>
                    <useFile>false</useFile>
                    <disableXmlReport>true</disableXmlReport>
                    <includes>
                        <include>**/*Test.*</include>
                        <include>**/*Suite.*</include>
                    </includes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.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>chapter1.HelloScala</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
</build>

(二)、项目编码

1、spark入门程序wordcount

package com.offcn.bigdata.spark.p1
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
/**
 * scala版本的wordcount
 */
object ScalaWordCountApp {
    def main(args: Array[String]): Unit = {
        val conf = new SparkConf()
            .setAppName(s"${ScalaWordCountApp.getClass.getSimpleName}")
            .setMaster("local[*]")
        val sc = new SparkContext(conf)
        //加载数据
        val file: RDD[String] = sc.textFile("file:/E:/data/spark/hello.txt")

       //按照分隔符进行切分
        val words:RDD[String] = lines.flatMap(line => line.split("\\s+"))

//每个单词记为1次
        val pairs:RDD[(String, Int)] = words.map(word => (word, 1))

//聚合数据
        val ret:RDD[(String, Int)] = pairs.reduceByKey(myReduceFunc)
        //export data to external system
        ret.foreach(println)

}
        sc.stop()
    }
    def myReduceFunc(v1: Int, v2: Int): Int = {
        v1 + v2
    }
}

2、Master URL说明

首先在编程过程中,至少需要给spark程序传递一个参数master-url,通过sparkConf.setMaster来完成。改参数,代表的是spark作业的执行方式,或者指定的spark程序的cluster-manager的类型。

master

含义

local

程序在本地运行,同时为本地程序提供一个线程来处理

local[M]

程序在本地运行,同时为本地程序分配M个工作线程来处理

local[*]

程序在本地运行,同时为本地程序分配机器可用的CPU core的个数工作线程来处理

local[M, N]

程序在本地运行,同时为本地程序分配M个工作线程来处理,如果提交程序失败,会进行最多N次的重试

spark://ip:port

基于standalone的模式运行,提交撑到ip对应的master上运行

spark://ip1:port1,ip2:port2

基于standalone的ha模式运行,提交撑到ip对应的master上运行

yarn/启动脚本中的deploy-mode配置为cluster

基于yarn模式的cluster方式运行,SparkContext的创建在NodeManager上面,在yarn集群中

yarn/启动脚本中的deploy-mode配置为client

基于yarn模式的client方式运行,SparkContext的创建在提交程序的那台机器上面,不在yarn集群中

3.Spark日志管理

(1)全局管理

就是项目classpath下面引入log4j.properties配置文件进行管理,由于我们这里已经配置过了项目的依赖管理,所以只需要将log4j.properties放置到spark-common模块的resources目录下即可。

# 基本日志输出级别为INFO,输出目的地为console
log4j.rootCategory=INFO, console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.target=System.err
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{1}: %m%n
# 输出配置的是spark提供的webui的日志级别
log4j.logger.org.spark_project.jetty=INFO
log4j.logger.org.spark_project.jetty.util.component.AbstractLifeCycle=ERROR
log4j.logger.org.apache.spark.repl.SparkIMain$exprTyper=INFO
log4j.logger.org.apache.spark.repl.SparkILoop$SparkILoopInterpreter=INFO
log4j.logger.org.apache.parquet=ERROR
log4j.logger.parquet=ERROR

(2)局部管理

就是在当前类中进行日志的管理。

import org.apache.log4j.{Level, Logger}
Logger.getLogger("org.apache.spark").setLevel(Level.WARN)
Logger.getLogger("org.apache.hadoop").setLevel(Level.WARN)
Logger.getLogger("org.spark_project").setLevel(Level.WARN)

(三)、spark程序的其他提交方式

1、加hdfs中的文件

object RemoteSparkWordCountOps {
    def main(args: Array[String]): Unit = {
        val conf = new SparkConf()
                .setMaster("local[*]")
                .setAppName("SparkWordCount")
        val sc = new SparkContext(conf)
        //load data from file
        val linesRDD:RDD[String] = sc.textFile("hdfs://ns1/data/spark/hello.txt")
        val ret = linesRDD.flatMap(_.split("\\s+")).map((_, 1)).reduceByKey(_ + _)
        ret.foreach{case (word, count) => println(word + "---" + count)}
        sc.stop()
    }

程序出现如下问题:

java.lang.IllegalArgumentException: java.net.UnknownHostException: ns1

解决方案,最简单的就是将hadoop的两个配置文件core-site.xml和hdfs-site.xml添加到项目的classpath中即可。

但是此时在此基础之上,将textFile去加载本地的文件

sc.textFile("E:/data/hello.txt")

则会报错:

java.lang.IllegalArgumentException: Pathname /E:/data/hello.txt from hdfs://ns1/E:/data/hello.txt is not a valid DFS filename

原因就在于,已经在classpath下面加载了hdfs-site.xml和core-site.xml的配置文件,则会自动理解输入的文件路径为hdfs的,自然会报错。所以,在此情况下还想加载本地文件,那么就告诉机器以本地文件的格式或者协议读取即可。

val linesRDD:RDD[String] = sc.textFile("file:/E:/data/hello.txt")

2.提交spark程序到集群中

首先需要将spark-core模块进行打包,其次上传到集群中,才可以进行提交作业到spark或者yarn集群中运行。

(1)Standalone集群

Client

bin/spark-submit \
--class chapter1.WordCount \
--master spark://node01:7077 \
/root/WordCount.jar \
hdfs://node01:8020/wordcount/input/words.txt

Cluster

bin/spark-submit \
--class chapter1.WordCount \
--master spark://node01:7077 \
/root/WordCount.jar \
hdfs://node01:8020/wordcount/input/words.txt \
hdfs://node01:8020/wordcount/input/output1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值