分布式计算平台Spark

分布式计算平台Spark:基础入门


20201216

一、课程

  1. 大数据组件

    • 分布式存储

      • Zookeeper:利用分布式存储系统实现小的核心数据的存储(加紧复习)

      • 抓紧复习

      • HDFS:离线大数据文件系统数据存储(加紧复习)

      • 抓紧复习

        • 为了解决大数据存储问题:分布式磁盘
      • Hive:离线数据仓库【表】

        • 为了解决统一化和规范化数据管理问题
      • Redis:实时内存式NOSQL数据库【所有数据都在内存中】

        • 为了解决数据高并发和高性能读写问题
      • HBASE:实时基于分布式内存的NoSQL数据库【内存+HDFS】(加紧复习)

      • 抓紧复习

        • 基于性能和大数据量之间做了一个平衡

        • 解决性能与存储之间的瓶颈的思想:冷热数据的分离

          • 冷数据:不经常被使用的数据

          • 热数据:经常被使用的数:最新的数据

            • 先产生的比较早的数据写入HDFS

            • 怎么保证读HDFS也能很快?

              • 构建数据存储的有序

              • 读缓存:BlockCache

                blockcache这个怎么实现的

              • 列族:存储:Store 如果不划分列族的情况下所有的列都存储在一个store

              • 设计列族的主要目的就是减少比较次数

          • 数据被使用的概率随着时间的流逝而逐渐降低

        • 二级索引:走两次索引,代替全表扫表

          • Phoenix
          • ES
      • Kafka:分布式实时消息队列【传递数据】(加紧复习)

        • 为了解决高可靠的实时场景下的数据实时缓存问题
        • 实时:磁盘文件、-》顺序写、pagecache:页缓存机制、zero copy
        • 核心:数据一次性语义
          • 有且仅处理一次,不重复,不丢失
      • ES:分布式全文检索搜索引擎

        • 构建全文索引
    • 分布式计算

      • 处理数据步骤:三步
        • step1:读取数据
          • 变量:Seq
        • step2:处理数据
          • 函数:map/filter/flatMap/zipwithindex/reduce/fold/group
        • step3:保存结果
      • MapReduce:离线批处理的分布式计算
        • Input:负责输入:InputFormat
          • TextInputFormat:文件
          • DBInputFormat:数据库
          • TableInputFormat:读HBASE
        • Map:MapTask处理每一个分片的数据
        • Shuffle:排序、分区、分组
        • Reduce:ReduceTask处理所有的数据
        • Output:负责输出
      • Spark
      • Flink
    • 数据采集

      • Flume
      • Sqoop
      • Logstash
      • FileBeat
    • 其他辅助性组件

      • Zookeeper:解决分布式存在的问题
        • 存储核心元数据信息:HBASE、Kafka
        • 解决HA问题
      • Hue:可视化操作平台
      • Oozie:分布式的调度平台
      • CM:集群管理平台

二、目标

  1. Spark的介绍

    • 什么是Spark?
    • Spark能实现什么功能?
    • 类似的工具,为什么选择Spark?
    • 基本的Spark的特点
  2. Spark环境部署

    • 架构

    • 集群搭建

    • 基本使用方式

三、Spark的起源与发展

1、分布式计算发展

  • 分布式计算发展

    • HPC:高性能计算
    • 云计算平台:虚拟机
      • 阿里云
      • 华为云
      • 亚马逊云
    • 大数据
      • 分布式存储
      • 分布式计算
  • 分布式计算平台的演变

    • 第一代:MapReduce

      • 设计:为了让廉价机器也能实现分布式处理
    • 第二代:Tez

    • 第三代:Spark

      • 设计:基于内存式的灵活性的编程计算框架
      • 以离线批处理为主
    • 第四代:Flink

      • 设计:流式高性能计算
  • 以实时数据流计算为主

为什么基于内存式的还没有流式的有优势?:见spark学习笔记中问题部分。

2、Spark诞生与发展

  • 诞生
    • 问题:最早使用MapReduce等工具实现分布式计算,出现了两个问题
      • MapReduce的计算过程非常慢,导致性能很差
      • Mapreduce编程非常死板(5大阶段不可调),不灵活
    • 解决:需要设计一些新的工具
      • databricks:研发一个新的工具,结合目前市场上很多分布式工具的特点,融合以后构建Spark
  • 发展
image-20201211132730546
  • 官网

    • spark.apache.org
    • databricks.com
  • 介绍

    image-20201216102659569

    Apache Spark is a lightning-fast unified analytics engine for big data and machine learning. It was originally developed at UC Berkeley in 2009.
    
    • lightning-fast:光速
    • unified analytics engine:统一化的分析引擎
      • 功能非常强大
      • 分析的类型
        • 离线代码开发
        • 交互式分析
        • 实时计算分析
        • Python
        • R
        • 机器学习
    • machine learning:机器学习
  • 定义:是一个分布式的统一化的计算框架;类似于前面学的MapReduce+yarn

3、Spark功能与特点

  • 官方对Spark的一个介绍

    At a high level, every Spark application consists of a driver program 
    #每个Spark程序都会包含一个驱动程序:Driver
    
    that runs the user’s main function 
    #这个driver运行在用户的main方法中
    
    and executes various parallel operations on a cluster. 
    #并且在集群中执行各种并行化操作 
     
    The main abstraction Spark provides is a resilient distributed dataset (RDD), 
    #Spark中提供了一个主要的抽象:RDD【弹性分布式数据集】【SparkCore中的核心数据结构】
    
    which is a collection of elements partitioned across the nodes of the cluster 
    # 被分区存储在各个节点中的一个元素的集合【类似于MapReduce中的分片的存在,所有分片构建一个RDD】
    
    that can be operated on in parallel.
    #可以被并行化的操作
    
    RDDs are created by starting with a file in the Hadoop file system (or any other Hadoop-supported file system), 
    #RDD可以被创建从一个Hadoop文件系统中被创建
    
    or an existing Scala collection in the driver program, and transforming it. 
    #或者从一个Scala的集合中进行创建,由driver来实现,并且对RDD进行转换
    
    Users may also ask Spark to persist an RDD in memory,
    #用户可以将RDD中的数据持久化【缓存】在内存中,
    【scala中结果会存在新生成的集合中这个集合可能会被回收:后边文档已有解决方案】
    allowing it to be reused efficiently across parallel operations. 
    #方便多次使用
    
    Finally, RDDs automatically recover from node failures.
    #最终,RDD会自动的从失败中恢复
    
    • RDD

      • 数据处理的流程

        • Input:读数据源,将数据源的数据封装到一个变量中
        • Transform:对这个变量的数据进行转换处理,得到结果
        • Output:将结果保存即可
      • MapReduce

        • 需求:1 + …… + 9

        • Input

          • 功能一:将数据进行分片,得到每个split

            • 目的:每个Task要处理一部分数据,先将数据划分
            • 举例:将1到9,分成若干个部分,分成3个部分
              • split1:1,2,3
              • split2:4,5,6
              • split3:7,8,9
          • 功能二:将每个分片的每条数据转换为KV结构

            • 目的:整个MapReduce中所有的数据都以KV结构进行存储和处理

              • split1

                (a,1)
                (a,2)
                (a,3)
                
              • split2

                (a,4)
                (a,5)
                (a,6)
                
              • split3

                (a,7)
                (a,8)
                (a,9)
                
        • Tranform

          • Map:每个Split启动MapTask进程进行处理,map方法
            • MapTask1:(a,6)
            • MapTask2:(a,15)
            • MapTask3:(a,24)
          • Reduce:启动一个ReduceTask来对所有Map的结果进行处理
            • ReduceTask:(a,45)
        • Output

        • 问题

          • MapReduce中的KV在很多场景下是不方便的
            • 只要存储一个值
            • 需要存储多个值
    • SparkCore

      • Input:读取数据

        • RDD:将读取到的所有数据放入RDD中

          • 问题:数据怎么划分?

            • RDD中的数据会被分区存储在不同的节点中
            • RDD的每个分区【partition】 = MapReduce中的每个分片【split】
          • 问题:RDD中存储的数据格式是什么样的?

            • RDD【T
              • RDD[String]
              • RDD[(String,Int)]
          • 理解:RDD类似于scala中的集合,但是RDD是分布式的,RDD集合中的数据分区存储在不同的机器上

            image-20201216115933763

            疑问这个rdd会随分区个数的变化重新将存储的数据分配到不同的节点上吗;会重新分配

      • TransForm:对RDD中的数据进行转换处理

        • RDD中很多的函数与Scala集合的函数是一致的
      • Output

    image-20201216121219624

  • Speed

    • 流程设计:读取、处理、保存

    • 保证整个流程中提高性能:积极的将数据存储在内存中

    • 问题:内存中的数据是不稳定的,空间较小

    • 解决

      • 如果内存不足以存放所有数据,将部分数据持久化persist在磁盘中 disk

      • 如果内存数据丢失,通过特殊的机制来保证数据可恢复或者可用

        • HDFS:副本机制

        • Redis:副本机制(内存、磁盘都有一份)

        • HBASE:WAL

        • WAL: Write-Ahead Logging [1] 预写日志系统;数据库中一种高效的日志算法,对于非内存数据库而言,磁盘I/O操作是数据库效率的一大瓶颈。在相同的数据量下,采用WAL日志的数据库系统事务提交时,磁盘写操作只有传统的回滚日志的一半左右,大大提高了数据库磁盘I/O操作的效率,从而提高了数据库的性能。

        • Kafka:副本机制

        • ES:副本机制

        • Spark能不能选用副本机制?

          • 不能,如果选用副本机制会占用更多的内存,依旧不能解决稳定性问题
          • 解决方案:血脉【记录所有数据的来源】
  • Ease of Use

    • 好使
    • 支持的开发接口比较多
      • Java
      • Scala
      • SQL
      • Python
      • R
  • Generality

    • 功能非常全面

      image-20201216104400434

    • SparkCore:Spark中最核心的组件

      • 类似于MapReduce,替代了MapReduce
      • 用于实现离线的批处理,可以使用Java、Scala进行开发代码
    • SparkSQL :Spark中用于实现SQL处理的组件(源自于hive)

      • 类似于Hive,用于替代Hive实现SQL计算
      • 支持SQL语句对数据仓库中的数据或者表的数据进行处理
    • SparkStreaming:准实时计算

      • 类似于Storm,用于实现实时计算
      • 准实时:用微小为单位的批处理来模拟实时计算
        • 例如:每200ms处理一次
      • 真实时:Storm、Flink!!!
        • 以数据为单位进行计算,产生一条数据,处理一条数据
    • SparkStructStreaming:结构化流

      • SQL + Streaming
    • Spark MLlib:机器学习的算法库

      • 工作中用算法库来实现算法模型的构建
      • 推荐模型的算法
    • Spark Graphx:图计算

      • 数据结构的图

    image-20201216110707181

  • Runs Everywhere

    • Spark支持各种数据源(内部已将封装了这些api)

      • 流程:读取、处理、保存

      • 数据源:读取、保存

      • 常用的数据源

        • SparkCore:HDFS、HBASE
        • SparkSQL:Hive、结构化数据【MySQL、Json、文件、Parquet(列式存储)】
        • SparkStreaming(流式数据):Kafka、HBASE、Redis

        image-20201216110000689

    • 运行在各种分布式资源平台中

      • http://spark.apache.org/docs/2.4.5/

      • 资源平台

        image-20201216110827697

      • Standalone

        • Spark自带的集群资源管理平台
      • Messos

        • 类似于YARN,国内应用的不多
      • YARN

        • 将Spark的程序放在YARN运行,由YARN做资源管理
      • Kubernetes

        • 新一代的分布式资源容器,类似于Docker

4、应用场景

  • 功能:用于实现各种场景下的分布式计算
  • 应用场景
    • 数据仓库:SparkCore实现ETL(解密、过滤等操作)
    • 数据分析
      • SparkSQL来实现数据离线分析
      • SparkStreaming或者StructStreaming来实现实时数据分析(flink取代的是这部分)
    • 推荐系统
      • Spark MLlib
  • 特点
    • 好使
    • 通用性
    • 支持多数据源和多平台

四、Spark环境部署测试

1、版本与编译

  • 版本

    • 1.x:早期的大数据平台所使用的版本,功能性能都有一些缺陷
    • 2.x:目前企业中应用最多的版本
      • 2.4.5
    • 3.x:最新的版本,增加了很多新的特性,用来提高性能
      • 目前暂时没有对应的应用环境
  • 发行厂商

    • Apache:http://archive.apache.org/dist/spark/spark-2.4.5/
    • CDH
      • 为什么不用Apache,而选用Cloudera公司的产品
        • 基于稳定性的考虑
      • Cloudera所提供的Spark版本是有缺陷的
        • Spark的编译好的包中是没有SparkSQL的
        • Cloudera公司自己有Impala
  • 基于以上的问题,需要基于Cloudera公司的依赖,自己编译Spark自己编译啥意思呀?

    spark-2.4.5-bin-cdh5.16.2-2.11.tgz
    

2、部署模式

  • 本地模式
    • 一般用于测试开发,没有分布式的主从架构
    • 将程序直接在本地启动一个JVM来运行
  • 集群模式
    • 一般用于生产环境,有分布式主从架构
    • 将程序提交给分布式资源平台去运行
    • 第一种:Standalone
      • Spark自带的集群资源管理
    • 第二种:YARN
      • 将Spark程序提交给YARN运行

Deploying部署:

3、架构组成

Spark cluster components

  • 主从架构模式

    • 主节点:管理集群
    • 从节点:负责实现计算
  • Standalone

    • 主:Master
    • 从:Worker
  • YARN

    • 主:ResourceManger
    • 从:NodeManager

    zookeeper解决单点故障问题,那么就自己实现了单点故障解决问题的功能

4、本地模式(Local)

[root@node1 spark]# hadoop-daemon.sh start namenode
[root@node1 spark]# hadoop-daemon.sh start datanode
#node1:50070端口
  • 参考附录一导入虚拟机

  • 参考附录二安装本地环境

    • 第一台机器恢复到快照3
    • 启动第一台机器即可
  • 启动HDFS

    hadoop-daemon.sh start namenode
    hadoop-daemon.sh start datanode
    
  • 测试

    • 启动Spark-shell

      cd /export/server/spark
      bin/spark-shell --master local[2]
      
      • spark-shell是Spark提供的一个交互式的Spark程序,可以通过命令行直接写Spark代码
      • –master:指定程序运行在哪个模式上
      • local:表示本地模式
        • [2]:运行这个程序,给定几核CPU
    • 创建测试文件

      hdfs dfs -mkdir /datas
      vim wordcount.data
      
      hadoop spark hbase
      hive hive hive hive
      hadoop spark spark
      
      hdfs dfs -put wordcount.data /datas
      #此文件在本地-》放到hdfs上
      
      
    - 观察Spark-shell日志
    
      ```shell
      Setting default log level to "WARN".
      #默认日志级别为WARN级别
      To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
      #如果你要修改日志级别,你要sc.setLogLevel(“INFO”)
      Spark context Web UI available at http://node1.itcast.cn:4040
      #每一个Spark程序都会自动开放一个Web监控界面,端口从4040开始,第二个程序的端口4041,依次类推
      Spark context available as 'sc' (master = local[2], app id = local-1608102687971).
      #创建了一个对象:sc:SparkContext
    Spark session available as 'spark'.
      #创建了一个对象:spark:SparkSession
    
    • SparkContext对象就是上午提到的driver programe
      • SparkSession对象是新一代的driver programe:里面包含了一个SparkContext对象
      • 用于替代老的SparkContext
  • 测试WordCount

    • Input:读HDFS中/datas/wordcount.data

      //调用sparkContext的方法读HDFS文件,存入RDD对象中
      scala> val inputRdd = sc.textFile("/datas/wordcount.data")
      inputRdd: org.apache.spark.rdd.RDD[String] = /datas/wordcount.data MapPartitionsRDD[1] at textFile at <console>:24
      //查看RDD的第一行数据
      scala> inputRdd.first
      res0: String = hadoop spark hbase
      //统计RDD的行数
      scala> inputRdd.count
      res1: Long = 3
      
        
    
      
    - Transform:实现词频统计
    
        - flatMap:RDD[String]
    
          ```scala
          
          scala> inputRdd.flatMap(line => line.trim.split("\\s+"))
          res2: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[2] at flatMap at <console>:26
          
          scala> inputRdd.flatMap(line => line.trim.split("\\s+")).foreach(println)
          hadoop
          spark
          hbase
          hive
          hive
          hive
          hive
          hadoop
        spark
          spark
    
    - map:RDD[(String,Int)]
    
      ```
      scala> inputRdd.flatMap(line => line.trim.split("\\s+")).map(word => (word,1)).foreach(println)
      (hadoop,1)
      (spark,1)
      (hbase,1)
      (hive,1)
      (hive,1)
      (hive,1)
      (hive,1)
      (hadoop,1)
    (spark,1)
      (spark,1)
    ```
    
    - reduceByKey:功能 = groupByKey + reduce:RDD[(String, Int)]
    
      ```
      scala> val rsRDD = inputRdd.flatMap(line => line.trim.split("\\s+")).map(word => (word,1)).reduceByKey((tmp,item)=> tmp+item)
      rsRDD: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[8] at reduceByKey at <console>:25
      
      scala> rsRDD.foreach(println)
      (hive,4)
      (spark,3)
    (hadoop,2)
      (hbase,1)
    ```
    

    • Output
      rsRDD.saveAsTextFile("/datas/output/output1")
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L55rTm6D-1610365374480)(Day38_分布式计算平台Spark:基础入门.assets/image-20201216155243915.png)]

    image-20201216155639241

    • 测试运行Jar包

      • spark-submit:用于运行Spark的jar包的

        • YARN语法

          yarn jar xxxx.jar  main_class args
          
      • Spark

        spark-submit 
        [选项]
        --class 指定运行哪个类
        xxxx.jar  
        args
        
      SPARK_HOME=/export/server/spark
      ${SPARK_HOME}/bin/spark-submit \
      --master local[2] \
      --class org.apache.spark.examples.SparkPi \
      ${SPARK_HOME}/examples/jars/spark-examples_2.11-2.4.5.jar \
      10
      

5、集群模式(Standalone)

  • 参考附录三安装集群环境

    • 先将第一台机器恢复到快照4

      image-20201216160339322

  • 启动Spark Standalone集群

    • 启动HDFS:第一台机器执行

      start-dfs.sh
      #创建一个目录,用于存储Spark程序的运行日志
      hdfs dfs -mkdir -p /spark/eventLogs/
      
    • 启动Master:第一台机器

      /export/server/spark/sbin/start-master.sh
      

      image-20201216162042582

    • 启动Worker:第一台机器

      /export/server/spark/sbin/start-slaves.sh
      

      image-20201216162122314

    • 查看WebUI

      node1:8080
      

      image-20201216162236884

    • 启动HistoryServer

      start-dfs.sh
      /export/server/spark/sbin/start-history-server.sh
      

      image-20201216162210834

    • 访问WebUI

      node1:18080
      

      image-20201216162354264

      image-20201220220104684

  • 测试

    SPARK_HOME=/export/server/spark
    ${SPARK_HOME}/bin/spark-submit \
    --master spark://node1:7077 \
    --class org.apache.spark.examples.SparkPi \
    ${SPARK_HOME}/examples/jars/spark-examples_2.11-2.4.5.jar \
    10
    

    image-20201216162713454

6、HA集群

  • 关闭所有Spark进程

    /export/server/spark/sbin/stop-slaves.sh 
    /export/server/spark/sbin/stop-master.sh 
    /export/server/spark/sbin/stop-history-server.sh
    
  • 修改配置文件

    cd /export/server/spark/conf/
    vim spark-env.sh
    
    #注释60行
    #SPARK_MASTER_HOST=node1
    #添加68行
    SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.deploy.zookeeper.url=node1:2181,node2:2181,node3:2181 -Dspark.deploy.zookeeper.dir=/spark-ha"
    
  • 分发

    cd /export/server/spark/conf
    scp -r spark-env.sh node2:$PWD
    scp -r spark-env.sh node3:$PWD
    
  • 启动ZK

    zookeeper-daemons.sh start
    zookeeper-daemons.sh status
    
  • 启动Master

    • 第一台

      /export/server/spark/sbin/start-master.sh
      
    • 第二台

      /export/server/spark/sbin/start-master.sh
      
  • 启动Worker

    /export/server/spark/sbin/start-slaves.sh 
    
  • 测试

    SPARK_HOME=/export/server/spark
    ${SPARK_HOME}/bin/spark-submit \
    --master spark://node1:7077,node2:7077 \
    --class org.apache.spark.examples.SparkPi \
    ${SPARK_HOME}/examples/jars/spark-examples_2.11-2.4.5.jar \
    100
    

五、Spark应用组成

1、应用组件

image-20201216164952350

  • Master:主节点进程

    • 类似于YARN中的ResourceManger
    • 管理集群以及所有从节点
    • 接受客户端请求
  • Worker:从节点进程:计算节点

    • 类似于YARN中的NodeManger
    • Work进程运行机器上:每个Work都能使用这台机器的一定的CPU和内存
  • HistoryServer:历史服务进程

  • Executor:Task真正运行的计算的进程

    • 类似于MapTask进程和ReduceTask进程
      • MapReduce以进程的方式来处理数据
      • Spark以线程的方式来实现数据处理
    • 就是Task运行所在的进程
    • 每个Executor运行在Work节点中
    • 每个Work节点会分配CPU和内存给每个Executor
    • 每个Work能用机器的1Core1GB
      • 每个Work上要启动Executor:每个Executor需要1core 512M的资源
      • 问:每个Worker上能启动几个Executor?、
  • Task:每个线程所处理的任务,每个线程需要1coreCPU来完成

  • Driver:每个Spark程序都要包含的一个进程,在代码中是:SparkContext对象

    • 负责解析构建所有Task
    • 分配以及监控和所有Task的运行

2、Web监控

image-20201216170616341

  • Application:一个Application就是一个Spark程序
  • job:一个程序中处理的单元
    • 以前MapReduce:一个Application就是一个Job
    • 现在Spark:一个Application可以多个job
  • Stage:每个Job会划分为多个阶段,每个阶段会用多个Task来实现这个阶段的处理的过程:执行计划
    • 为什么需要Stage?
      • 程序是基于lazy模式构建RDD,最终触发job的运行,通过DAG可以根据执行计划来一步步执行
    • stage的划分规则?
      • 是否产生shuffle过程
    • stage怎么变成Task呢?
      • Stage中每个RDD的每个分区需要使用一个Task来运行处理

六、开发环境搭建测试

1、创建Maven工程引入依赖

  • 附录四中依赖

2、WordCount开发

package bigdata.itcast.cn.spark.scala.wordcount

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

/**
  * @ClassName SparkCoreWordCount
  * @Description TODO 自己开发代码来实现Wordcount
  * @Date 2020/12/16 17:22
  * @Create By     Frank
  */
object SparkCoreWordCount {
  def main(args: Array[String]): Unit = {
    /**
      * step1:先构建SparkContext:初始化资源对象
      */

    //构建一个SparkConf:用于管理当前程序的所有配置
    val conf = new SparkConf()
      //给当前程序设置一个名字
      .setAppName(this.getClass.getSimpleName.stripSuffix("$"))
      //设置当前程序运行的模式
      .setMaster("local[2]")
    //构建一个SparkContext对象
    val sc = new SparkContext(conf)
    //调整日志级别
    sc.setLogLevel("WARN")

    /**
      * step2:处理数据
      */
    //todo:1-读取数据
    val inputRdd: RDD[String] = sc.textFile("/datas/wordcount.data")
    //todo:2-处理数据
    val rsRdd = inputRdd
        .filter(line => null != line && line.trim.length >0)
        .flatMap(line => line.trim.split("\\s+"))
        .map(word => word -> 1)
        .reduceByKey((tmp,item) => tmp+item)
    
    //todo:3-保存结果
    rsRdd.foreach(println)

    /**
      * step3:释放资源
      */
    Thread.sleep(1000000L)
    sc.stop()
  }
}

3、基础模板开发

package bigdata.itcast.cn.spark.scala.mode

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

/**
  * @ClassName SparkCoreMode
  * @Description TODO SparkCore的基础模板
  * @Date 2020/12/16 17:22
  * @Create By     Frank
  */
object SparkCoreMode {
  def main(args: Array[String]): Unit = {
    /**
      * step1:先构建SparkContext:初始化资源对象
      */

    //构建一个SparkConf:用于管理当前程序的所有配置
    val conf = new SparkConf()
      //给当前程序设置一个名字
      .setAppName(this.getClass.getSimpleName.stripSuffix("$"))
      //设置当前程序运行的模式
      .setMaster("local[2]")
    //构建一个SparkContext对象
    val sc = new SparkContext(conf)
    //调整日志级别
    sc.setLogLevel("WARN")

    /**
      * step2:处理数据
      */
    //todo:1-读取数据
    //todo:2-处理数据
    //todo:3-保存结果

    /**
      * step3:释放资源
      */
    Thread.sleep(1000000L)
    sc.stop()
  }
}

4、TopKey开发

package bigdata.itcast.cn.spark.scala.topkey

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

/**
  * @ClassName SparkCoreWordCount
  * @Description TODO 取单词最多的前3个
  * @Date 2020/12/16 17:22
  * @Create By     Frank
  */
object SparkCoreWordCountTopWord {
  def main(args: Array[String]): Unit = {
    /**
      * step1:先构建SparkContext:初始化资源对象
      */

    //构建一个SparkConf:用于管理当前程序的所有配置
    val conf = new SparkConf()
      //给当前程序设置一个名字
      .setAppName(this.getClass.getSimpleName.stripSuffix("$"))
      //设置当前程序运行的模式
      .setMaster("local[2]")
    //构建一个SparkContext对象
    val sc = new SparkContext(conf)
    //调整日志级别
    sc.setLogLevel("WARN")

    /**
      * step2:处理数据
      */
    //todo:1-读取数据
    val inputRdd: RDD[String] = sc.textFile("/datas/wordcount.data")
    //todo:2-处理数据
    inputRdd
        .filter(line => null != line && line.trim.length >0)
        .flatMap(line => line.trim.split("\\s+"))
        .map(word => word -> 1)
        .reduceByKey((tmp,item) => tmp+item)
        //排序方式一:sortByKey:按照Key进行排序
//        .map(tuple => tuple.swap)
//        .sortByKey(ascending = false)
        //排序方式二:sortBy :指定按照哪个值进行排序
        .sortBy(tuple => tuple._2,false)
        .take(3)
        .foreach(println)


    //todo:3-保存结果
//    rsRdd.foreach(println)

    /**
      * step3:释放资源
      */
    Thread.sleep(1000000L)
    sc.stop()
  }
}

附录一:导入Spark环境虚拟机

1、拷贝三台机器

image-20201212173533573

2、导入三台机器

image-20201212173641568

3、启动三台机器

  • 第二台、第三台启动会遇到这个报错,选择浏览
image-20201212173718221
  • 浏览中,选择第一台机器的vmx文件即可

    image-20201212173837761

4、Windows配置映射

image-20201212174930816

192.168.88.100   node1.itcast.cn   node1
192.168.88.101   node2.itcast.cn   node2
192.168.88.102   node3.itcast.cn   node3

附录二:本地模式安装

【以第一台机器为例】

  • 解压安装

    tar -zxvf /export/software/spark-2.4.5-bin-cdh5.16.2-2.11.tgz -C /export/server/
    ln -s /export/server/spark-2.4.5-bin-cdh5.16.2-2.11 /export/server/spark
    
    • 常见的目录
      • bin:客户端命令
      • sbin:集群管理命令,服务的启动和关闭
      • conf:配置文件目录
      • jars:存放jar包的目录
  • 修改配置

  • spark-env.sh.template 配置环境变量的

    cd /export/server/spark/conf
    mv spark-env.sh.template spark-env.sh
    vim spark-env.sh
    
    #22行-23行
    JAVA_HOME=/export/server/jdk
    SCALA_HOME=/export/server/scala
    #30行
    HADOOP_CONF_DIR=/export/server/hadoop/etc/hadoop
    

附录三:Standalone集群模式

1、恢复三台机器快照

  • 架构:分布式主从架构

    • 主:Master
      • 第一台机器
    • 从:Worker
      • 三台机器
  • 将三台机器恢复到《4、分布式环境》

  • 解压安装

    tar -zxvf /export/software/spark-2.4.5-bin-cdh5.16.2-2.11.tgz -C /export/server/
    ln -s /export/server/spark-2.4.5-bin-cdh5.16.2-2.11 /export/server/spark
    

2、修改进程配置

  • spark-env.sh

    cd /export/server/spark/conf/
    mv spark-env.sh.template spark-env.sh
    vim spark-env.sh
    
    #22行-23行
    JAVA_HOME=/export/server/jdk
    SCALA_HOME=/export/server/scala
    
    #30行
    HADOOP_CONF_DIR=/export/server/hadoop/etc/hadoop
    #60行
    #指定Master启动的地址
    SPARK_MASTER_HOST=node1
    #指定Master的通信端口
    SPARK_MASTER_PORT=7077
    #Master的Web端口
    SPARK_MASTER_WEBUI_PORT=8080
    #指定每个Work能使用这台机器的多少核CPU
    SPARK_WORKER_CORES=1
    #指定每个Work能使用这台机器的多少内存
    SPARK_WORKER_MEMORY=1g
    #Work的端口
    SPARK_WORKER_PORT=7078
    #Work的web端口
    SPARK_WORKER_WEBUI_PORT=8081
    #配置Spark程序日志的记录位置
    SPARK_HISTORY_OPTS="-Dspark.history.fs.logDirectory=hdfs://node1:8020/spark/eventLogs/ -Dspark.history.fs.cleaner.enabled=true"
    
    • MapReduce:JobHistoryServer
      • 用于记录之前所运行的所有MapReduce的程序
    • Spark:HistoryServer
      • 用于记录Spark中运行的所有程序,会将所有程序运行的日志存储在HDFS上
  • spark-defaults.conf:类似于我们以前讲的site文件

    cd /export/server/spark/conf/
    hdfs dfs -mkdir -p /spark/eventLogs/
    mv spark-defaults.conf.template spark-defaults.conf 
    vim spark-defaults.conf
    
    #28行
    #启用日志存储
    spark.eventLog.enabled true
    #日志存储位置
    spark.eventLog.dir hdfs://node1:8020/spark/eventLogs/
    #启用压缩存储日志
    spark.eventLog.compress true
    

3、修改Worker配置

cd /export/server/spark/conf/
mv slaves.template slaves 
vim slaves
node1
node2
node3

4、日志级别调整

cd /export/server/spark/conf/
mv log4j.properties.template log4j.properties
vim log4j.properties
#修改19行
log4j.rootCategory=WARN, console

5、分发

  • 所有节点配置免秘钥登录

    ssh-copy-id node1
    ssh-copy-id node2
    ssh-copy-id node3
    
  • 分发Spark

    cd /export/server/
    scp -r spark-2.4.5-bin-cdh5.16.2-2.11 node2:$PWD
    scp -r spark-2.4.5-bin-cdh5.16.2-2.11 node3:$PWD
    
  • 第二台和第三台创建软连接

    ln -s /export/server/spark-2.4.5-bin-cdh5.16.2-2.11 /export/server/spark
    

附录四:Spark Maven依赖

	<!-- 指定仓库位置,依次为aliyun、cloudera和jboss仓库 -->
    <repositories>
        <repository>
            <id>aliyun</id>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        </repository>
        <repository>
            <id>cloudera</id>
            <url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
        </repository>
        <repository>
            <id>jboss</id>
            <url>http://repository.jboss.com/nexus/content/groups/public</url>
        </repository>
    </repositories>

    <properties>
        <scala.version>2.11.12</scala.version>
        <scala.binary.version>2.11</scala.binary.version>
        <spark.version>2.4.5</spark.version>
        <hadoop.version>2.6.0-cdh5.16.2</hadoop.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_${scala.binary.version}</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
    </dependencies>

    <build>
        <outputDirectory>target/classes</outputDirectory>
        <testOutputDirectory>target/test-classes</testOutputDirectory>
        <resources>
            <resource>
                <directory>${project.basedir}/src/main/resources</directory>
            </resource>
        </resources>
        <!-- Maven 编译的插件 -->
        <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>
                </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>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

附录五:IDEA连接远程文件系统

image-20201211174825938 image-20201211191341170 image-20201211191423708 image-20201211191450408
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

章鱼哥TuNan&Z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值