spark的运行架构和代码开发

spark的运行架构

以standalone为例:
在这里插入图片描述
在这里插入图片描述

Driver Program :运⾏main函数并且新建SparkContext的程序。
Application:基于Spark的应用程序,包含了driver程序和集群上的executor。Cluster Manager:指的是在集群上获取资源的外部服务。目前有三种类型
(1)Standalone: spark原生的资源管理,由Master负责资源的分配
(2)Apache Mesos:与hadoop MR兼容性良好的一种资源调度框架
(3)Hadoop Yarn: 主要是指Yarn中的ResourceManager
Worker Node: 集群中任何可以运行Application代码的节点,在Standalone模式中指的是通过slaves文件配置的Worker节点,在Spark on Yarn模式下就是NodeManager节点
Executor:是在一个worker node上为某应⽤启动的⼀个进程,该进程负责运⾏任务,并且负责将数据存在内存或者磁盘上。每个应⽤都有各自独立的executor。
Task :被送到某个executor上的工作单元。

spark任务提交以及spark-shell使用

spark任务提交说明
对于需要打包运行的spark任务,就可以使用bin/spark-submit脚本启动应用了. 这个脚本负责设置spark使用的classpath和依赖,支持不同类型的集群管理器和发布模式:

bin/spark-submit \
  --class <main-class>
  --master <master-url> \
  --deploy-mode <deploy-mode> \
  --conf <key>=<value> \
  ... # other options
  <application-jar> \
  [application-arguments]

一些常用选项:
–class: 你的应用的启动类 (如 org.apache.spark.examples.SparkPi)
–master: 集群的master URL (如 spark://node01:7077)
–deploy-mode: 是否发布你的驱动到worker节点(cluster) 或者作为一个本地客户端 (client) (default: client)*
–conf: 任意的Spark配置属性, 格式key=value. 如果值包含空格,可以加引号“key=value”. 缺省的Spark配置
–application-jar: 打包好的应用jar,包含依赖. 这个URL在集群中全局可见。 比如hdfs:// 共享存储系统, 如果是 file:// path, 那么所有的节点的path都包含同样的jar.
–application-arguments: 传给main()方法的参数

–master MASTER_URL
可以是spark://host:port, mesos://host:port, yarn, yarn-cluster,yarn-client, local
–deploy-mode DEPLOY_MODE
Driver程序运行的地方,client或者cluster
–class CLASS_NAME
主类名称,含包名
–name NAME
Application名称
–jars JARS
Driver依赖的第三方jar包
–py-files PY_FILES
用逗号隔开的放置在Python应用程序PYTHONPATH上的.zip, .egg, .py文件列表
–files FILES
用逗号隔开的要放置在每个executor工作目录的文件列表
–properties-file FILE
设置应用程序属性的文件路径,默认是conf/spark-defaults.conf
–driver-memory MEM
Driver程序使用内存大小
–driver-java-options
–driver-library-path
Driver程序的库路径
–driver-class-path
Driver程序的类路径
–executor-memory MEM
executor内存大小,默认1G
–driver-cores NUM
Driver程序的使用CPU个数,仅限于Spark Alone模式
–supervise
失败后是否重启Driver,仅限于Spark Alone模式
–total-executor-cores NUM
executor使用的总核数,仅限于Spark Alone、Spark on Mesos模式
–executor-cores NUM
每个executor使用的内核数,默认为1,仅限于Spark on Yarn模式
–queue QUEUE_NAME
提交应用程序给哪个YARN的队列,默认是default队列,仅限于Spark on Yarn模式
–num-executors NUM
启动的executor数量,默认是2个,仅限于Spark on Yarn模式
–archives ARCHIVES
仅限于Spark on Yarn模式

参数说明:
在这里插入图片描述

使用案例

运行spark-shell --master local[N] 读取本地文件

单机模式:通过本地N个线程跑任务,只运行一个SparkSubmit进程。
创建本地文件,使用spark程序实现单词计数统计
第一步:准备本地文件

mkdir -p /export/servers/sparkdatas
cd /export/servers/sparkdatas/
vim wordcount.txt
hello me
hello you
hello her

第二步:通 --master启动本地模式

cd /export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/
bin/spark-shell --master local[2]

第三步:开发scala单词统计代码(spark中没有flatter方法,用flatmap来代替)

sc.textFile("file:///export/servers/sparkdatas/wordcount.txt").flatMap(x => x.split(" ")).map(x => (x,1)).reduceByKey((x,y) => x + y).collect
或者使用以下这种方式,通过下划线来进行替代
sc.textFile("file:///export/servers/sparkdatas/wordcount.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(_ + _).collect

统计过程:
在这里插入图片描述
运行spark-shell --master local[N] 读取hdfs上面的文件
第一步:将我们的数据文件上传hdfs

cd /export/servers/sparkdatas
hdfs dfs -mkdir -p /sparkwordcount
hdfs dfs -put wordcount.txt  /sparkwordcount

第二步:开发spark的程序

sc.textFile("hdfs://node01:8020/sparkwordcount/wordcount.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(_ + _).collect

通过scala来开发spark

导入POM依赖

<properties>
        <scala.version>2.11.8</scala.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.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.7.5</version>
        </dependency>
    </dependencies>
    <build>
        <sourceDirectory>src/main/scala</sourceDirectory>
        <testSourceDirectory>src/test/scala</testSourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                    <!--    <verbal>true</verbal>-->
                </configuration>
            </plugin>
            <plugin>
                <groupId>net.alchim31.maven</groupId>
                <artifactId>scala-maven-plugin</artifactId>
                <version>3.2.0</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>3.1.1</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>
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

import scala.collection.mutable

object SparkFirst {

  /**
    * 主程序的入口,实现单词计数统计
    * @param args
    */
  def main(args: Array[String]): Unit = {
    //获取sparkContext

    val sparkConf: SparkConf = new SparkConf().setMaster("local[2]").setAppName("scalaCount")

    //将程序打包到spark集群上面去运行
    val sparkConf: SparkConf = new SparkConf().setAppName("scalaCount")//.setMaster("local[2]")

    val sc = new SparkContext(sparkConf)
    sc.setLogLevel("WARN")

    //读取文件得到fileRDD
   val fileRDD: RDD[String] = sc.textFile("file:///F:\\wordcount.txt")
    
    //打包运行
    val fileRDD: RDD[String] = sc.textFile(args(0))

    //对文件内容进行切分压平
    val word: RDD[String] = fileRDD.flatMap(x => x.split(" "))
    //对每个单词记做 1  次
    val wordAndOne: RDD[(String, Int)] = word.map(x =>(x,1))
    //将相同的单词进行累加
    val wordNum: RDD[(String, Int)] = wordAndOne.reduceByKey(_  + _)

    //累加之后的结果进行排序
        val sortBy: RDD[(String, Int)] = wordNum.sortBy(x => x._2,)//升序

    val sortBy: RDD[(String, Int)] = wordNum.sortBy(x => x._2,false)//降序

    //将结果打印出来
    val collect: Array[(String, Int)] = sortBy.collect()
    val toBuffer: mutable.Buffer[(String, Int)] = collect.toBuffer
    println(toBuffer)

    //将统计结果保存到文件里面去
    //sortBy.saveAsTextFile("file:///F:\\wordcount\\spark_out")

    sortBy.saveAsTextFile(args(1))


    //关闭sparkContext
    sc.stop()

  }


}

运行spark的jar包程序
通过spark-submit脚本来提交我们开发的jar包

bin/spark-submit  \
--class cn.itcast.spark.wordcount.WordCount \
--master spark://node01:7077 \
--executor-memory 1g \
--total-executor-cores 2 \
/export/servers/original-day01-1.0-SNAPSHOT.jar \
hdfs://node01:8020/sparkwordcount/wordcount.txt  \
hdfs://node01:8020/sparkwordcount_out  

使用java来开发spark

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.FlatMapFunction;
import org.apache.spark.api.java.function.Function2;
import org.apache.spark.api.java.function.PairFunction;
import scala.Tuple2;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class JavaSpark {

    /**
     * 程序的入口类
     * @param args
     */
    public static void main(String[] args) {
        //获取驱动类JavaSparkContext
        SparkConf sparkConf = new SparkConf().setMaster("local[2]").setAppName("javaSpark");

        JavaSparkContext javaSparkContext = new JavaSparkContext(sparkConf);
        //读取文件
        JavaRDD<String> fileRDD = javaSparkContext.textFile("file:///F:\\scala与spark课件资料教案\\3、spark课程\\1、spark第一天\\wordcount\\wordcount.txt");

        //对文件进行切分压平
        /**
         * FlatMapFunction<String, String> 跟两个参数
         * 第一个参数是输入数据类型,就是我们一行行的数据
         * 第二个参数就是我们输出结果类型,就是一个个的单词,还是String
         */
        JavaRDD<String> words = fileRDD.flatMap(new FlatMapFunction<String, String>() {
            /**
             *实现call方法,跟了一个参数  line  就是我们一行行的数据
             * @param line
             * @return
             * @throws Exception
             */
            @Override
            public Iterator<String> call(String line) throws Exception {
                String[] split = line.split(" ");
                //将切割之后的数组转换成为Iterator类型
                Iterator<String> iterator = Arrays.asList(split).iterator(); //转成所需的Iterator

                return iterator;
            }
        });

        //将每一个单词记做1
        /***
         * PairFunction 跟了三个参数
         * 第一个参数,是我们输入的数据类型,每个单词
         * 第二个参数是我们元组的第一位类型
         * 第三个参数是我们元组的第二位类型
         */
        JavaPairRDD<String, Integer> wordAndOne = words.mapToPair(new PairFunction<String, String, Integer>() {
            /**
             *
             * @param word  就是我们输入的一个个的单词
             * @return
             * @throws Exception
             */
            @Override
            public Tuple2<String, Integer> call(String word) throws Exception {
                Tuple2<String, Integer> stringIntegerTuple2 = new Tuple2<>(word, 1);

                return stringIntegerTuple2;
            }
        });

        //将相同单词进行累加
        JavaPairRDD<String, Integer> reduceByKey = wordAndOne.reduceByKey(new Function2<Integer, Integer, Integer>() {
            /**
             *
             * @param v1  每个单词出现次数  1
             * @param v2  累加之后的历史结果值
             * @return
             * @throws Exception
             */
            @Override
            public Integer call(Integer v1, Integer v2) throws Exception {
                return v1 + v2;
            }
        });
        //打印输出结果
        List<Tuple2<String, Integer>> collect = reduceByKey.collect();
        for (Tuple2<String, Integer> stringIntegerTuple2 : collect) {
            System.out.println(stringIntegerTuple2._1  + "=====" +  stringIntegerTuple2._2);
        }
        javaSparkContext.stop();
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值