2021-02-22 大数据课程笔记 day33

时间煮雨
@R星校长

Spark 第五天【SparkCore 内容】

主要内容

  1. 广播变量和累加器
  2. Spark webui 界面
  3. Spark 历史日志服务器配置
  4. Spark MasterHA
  5. Spark Shuffle
  6. Spark Shuffle 文件寻址
  7. Spark 内存管理
  8. Spark Shuffle 优化
    在这里插入图片描述

第一节 Spark 广播变量和累加器

  1. 广播变量
  • 广播变量理解图在这里插入图片描述
  • 广播变量使用
val conf = new SparkConf()
conf.setMaster("local").setAppName("brocast")
val sc = new SparkContext(conf)
val list = List("hello xasxt")
val broadCast = sc.broadcast(list)
val lineRDD = sc.textFile("./words.txt")
lineRDD.filter { x => broadCast.value.contains(x) }.foreach { println}
sc.stop()
  • 注意事项
    • 能不能将一个 RDD 使用广播变量广播出去?
      不能,因为 RDD 是不存储数据的。可以将 RDD 的结果广播出去。
    • 广播变量只能在 Driver 端定义,不能在 Executor 端定义。
    • 在 Driver 端可以修改广播变量的值,在 Executor 端无法修改广播变量的值。
  1. 累加器
  • 累加器理解图在这里插入图片描述
  • 累加器的使用
val conf = new SparkConf()
conf.setMaster("local").setAppName("accumulator")
val sc = new SparkContext(conf)
val accumulator = sc.accumulator(0)
sc.textFile("./words.txt").foreach { x =>{accumulator.add(1)}}
println(accumulator.value)
sc.stop()
  • 注意事项
    • 累加器在 Driver 端定义赋初始值,累加器只能在 Driver 端读取,在 Excutor 端更新。

第二节 Spark webui 界面

  1. SparkUI 界面介绍
    可以指定提交 Application 的名称
    ./spark-shell --master spark://node1:7077 --name myapp
  2. 配置 historyServer
  • 临时配置,对本次提交的应用程序起作用
./spark-shell --master spark://node1:7077 
--name myapp1
--conf spark.eventLog.enabled=true
 --conf spark.eventLog.dir=hdfs://node1:9000/spark/test

停止程序,在 Web Ui 中 Completed Applications 对应的 ApplicationID 中能查看 history。

  • spark-default.conf 配置文件中配置 HistoryServer,对所有提交的 Application 都起作用
    在客户端节点,进入../spark-1.6.0/conf/ spark-defaults.conf最后加入:
//开启记录事件日志的功能
spark.eventLog.enabled           true
//设置事件日志存储的目录
spark.eventLog.dir               hdfs://node1:9000/spark/test
//设置 HistoryServer 加载事件日志的位置
spark.history.fs.logDirectory    hdfs://node1:9000/spark/test
//日志优化选项,压缩日志
spark.eventLog.compress          true

启动HistoryServer:

./start-history-server.sh

访问HistoryServer:node4:18080 , 之后所有提交的应用程序运行状况都会被记录。

第三节 Spark Master HA

  1. Master 的高可用原理
    Standalone 集群只有一个 Master,如果 Master 挂了就无法提交应用程序,需要给 Master 进行高可用配置,Master 的高可用可以使用 fileSystem (文件系统)和 zookeeper(分布式协调服务)。
    fileSystem 只有存储功能,可以存储 Master 的元数据信息,用 fileSystem 搭建的 Master 高可用,在 Master 失败时,需要我们手动启动另外的备用 Master,这种方式不推荐使用。
    zookeeper 有选举和存储功能,可以存储 Master 的元素据信息,使用 zookeeper 搭建的 Master 高可用,当 Master 挂掉时,备用的 Master 会自动切换,推荐使用这种方式搭建 Master 的 HA。在这里插入图片描述
  2. Master 高可用搭建
    1) 在 Spark Master 节点上配置主 Master,配置 spark-env.sh
export SPARK_DAEMON_JAVA_OPTS="
-Dspark.deploy.recoveryMode=ZOOKEEPER
-Dspark.deploy.zookeeper.url=node3:2181,node4:2181,node5:2181 
-Dspark.deploy.zookeeper.dir=/sparkmaster0821"

在这里插入图片描述
2) 发送到其他 worker 节点上在这里插入图片描述
在这里插入图片描述
3) 找一台节点(非主 Master 节点)配置备用 Master , 修改 spark-env.sh 配置节点上的 MasterIP在这里插入图片描述
4) 启动集群之前启动 zookeeper 集群:

../zkServer.sh start

5) 启动 spark Standalone 集群,启动备用 Master
6) 打开主 Master 和备用 Master WebUI 页面,观察状态。

  1. 注意点
  • 主备切换过程中不能提交 Application。
  • 主备切换过程中不影响已经在集群中运行的 Application。因为 Spark 是粗粒度资源调度。
  1. 测试验证
    提交 SparkPi 程序,kill 主 Master 观察现象。
./spark-submit 
--master spark://node1:7077,node2:7077 
--class org.apache.spark.examples.SparkPi 
../lib/spark-examples-1.6.0-hadoop2.6.0.jar 
10000

第四节 Spark Shuffle

1. SparkShuffle 概念

reduceByKey 会将上一个 RDD 中的每一个 key 对应的所有 value 聚合成一个 value,然后生成一个新的 RDD,元素类型是 <key,value> 对的形式,这样每一个 key 对应一个聚合起来的 value。
问题:聚合之前,每一个 key 对应的 value 不一定都是在一个 partition 中,也不太可能在同一个节点上,因为 RDD 是分布式的弹性的数据集,RDD 的 partition 极有可能分布在各个节点上。
如何聚合?
– Shuffle Write:上一个 stage 的每个 map task 就必须保证将自己处理的当前分区的数据相同的 key 写入一个分区文件中,可能会写入多个不同的分区文件中。
– Shuffle Read:reduce task 就会从上一个 stage 的所有 task 所在的机器上寻找属于己的那些分区文件,这样就可以保证每一个 key 所对应的 value 都会汇聚到同一个节点上去处理和聚合。
Spark 中有两种 Shuffle 管理类型,HashShufflManager 和 SortShuffleManager,Spark1.2 之前是 HashShuffleManager, Spark1.2 引入SortShuffleManager, 在 Spark 2.0+ 版本中已经将 HashShuffleManager 丢弃。

2. HashShuffleManager

1) 普通机制

  • 普通机制示意图在这里插入图片描述
  • 执行流程
    a) 每一个 map task 将不同结果写到不同的 buffer 中,每个 buffer 的大小为 32K。buffer 起到数据缓存的作用。
    b) 每个 buffer 文件最后对应一个磁盘小文件。
    c) reduce task 来拉取对应的磁盘小文件。
  • 总结
    ① .map task 的计算结果会根据分区器(默认是 hashPartitioner)来决定写入到哪一个磁盘小文件中去。ReduceTask 会去 Map 端拉取相应的磁盘小文件。
    ② .产生的磁盘小文件的个数:
    M(map task 的个数)*R(reduce task 的个数)
  • 存在的问题
    产生的磁盘小文件过多,会导致以下问题:
    a) 在 Shuffle Write 过程中会产生很多写磁盘小文件的对象。
    b) 在 Shuffle Read 过程中会产生很多读取磁盘小文件的对象。
    c) 在 JVM 堆内存中对象过多会造成频繁的 gc , gc 还无法解决运行所需要的内存 的话,就会 OOM。
    d) 在数据传输过程中会有频繁的网络通信,频繁的网络通信出现通信故障的可能性大大增加,一旦网络通信出现了故障会导致 shuffle file cannot find 由于这个错误导致的 task 失败,TaskScheduler 不负责重试,由 DAGScheduler 负责重试 Stage。

2) 合并机制

  • 合并机制示意图在这里插入图片描述
  • 总结
    产生磁盘小文件的个数:C(core 的个数)*R(reduce 的个数)

3. SortShuffleManager

1) 普通机制

  • 普通机制示意图在这里插入图片描述
  • 执行流程
    a) map task 的计算结果会写入到一个内存数据结构里面,内存数据结构默认是 5M
    b) 在 shuffle 的时候会有一个定时器,不定期的去估算这个内存结构的大小,当内存结构中的数据超过 5M 时,比如现在内存结构中的数据为 5.01M,那么他会申请 5.01*2-5=5.02M 内存给内存数据结构。
    c) 如果申请成功不会进行溢写,如果申请不成功,这时候会发生溢写磁盘。
    d) 在溢写之前内存结构中的数据会进行排序分区
    e) 然后开始溢写磁盘,写磁盘是以 batch 的形式去写,一个 batch 是 1 万条数据,
    f) map task 执行完成后,会将这些磁盘小文件合并成一个大的磁盘文件,同时生成一个索引文件。
    g) reduce task 去 map 端拉取数据的时候,首先解析索引文件,根据索引文件再去拉取对应的数据。
  • 总结
    产生磁盘小文件的个数: 2*M(map task 的个数)

2) bypass 机制

  • bypass 机制示意图在这里插入图片描述
  • 总结
    ① .bypass 运行机制的触发条件如下:
    shuffle reduce task 的数量小于 spark.shuffle.sort.bypassMergeThreshold 的参数值。这个值默认是 200。
    ② .产生的磁盘小文件为:2*M(map task 的个数)

第五节 Spark Shuffle 文件寻址

  1. Shuffle 文件寻址

1) MapOutputTracker
MapOutputTracker 是 Spark 架构中的一个模块,是一个主从架构。管理磁盘小文件的地址。

  • MapOutputTrackerMaster 是主对象,存在于 Driver 中。
  • MapOutputTrackerWorker 是从对象,存在于 Excutor 中。

2) BlockManager
BlockManager 块管理者,是 Spark 架构中的一个模块,也是一个主从架构。

  • BlockManagerMaster , 主对象,存在于 Driver 中。
    BlockManagerMaster 会在集群中有用到广播变量和缓存数据或者删除缓存数据的时候,通知 BlockManagerSlave 传输或者删除数据。
  • BlockManagerSlave,从对象,存在于 Excutor 中。
    BlockManagerSlave 会与 BlockManagerSlave 之间通信。
  • 无论在 Driver 端的 BlockManager 还是在 Excutor 端的 BlockManager 都含有三个对象:
    ① DiskStore: 负责磁盘的管理。
    ② MemoryStore: 负责内存的管理。
    ③ BlockTransferService: 负责数据的传输。

3) Shuffle 文件寻址图在这里插入图片描述
4) Shuffle 文件寻址流程

a) 当 map task 执行完成后,会将 task 的执行情况和磁盘小文件的地址封装到 MpStatus 对象中,通过 MapOutputTrackerWorker 对象向 Driver 中的 MapOutputTrackerMaster 汇报。

b) 在所有的 map task 执行完毕后,Driver 中就掌握了所有的磁盘小文件的地址。

c) 在 reduce task 执行之前,会通过 Excutor 中 MapOutPutTrackerWorker 向 Driver 端的 MapOutputTrackerMaster 获取磁盘小文件的地址。

d) 获取到磁盘小文件的地址后,会通过 BlockManager 连接数据所在节点,然后通过 BlockTransferService 进行数据的传输。

e) BlockTransferService 默认启动 5 个 task 去节点拉取数据。默认情况下,5 个 task 拉取数据量不能超过 48M。

第六节 Spark 内存管理和 Shuffle 优化

Spark内存管理

Spark执行应用程序时,Spark集群会启动Driver和Executor两种JVM进程,Driver负责创建SparkContext上下文,提交任务,task的分发等。Executor负责task的计算任务,并将结果返回给Driver。同时需要为需要持久化的RDD提供储存。Driver端的内存管理比较简单,这里所说的Spark内存管理针对Executor端的内存管理。

Spark内存管理分为静态内存管理和统一内存管理,Spark1.6之前使用的是静态内存管理,Spark1.6之后引入了统一内存管理。

静态内存管理中存储内存、执行内存和其他内存的大小在 Spark 应用程序运行期间均为固定的,但用户可以应用程序启动前进行配置。

统一内存管理与静态内存管理的区别在于储存内存和执行内存共享同一块空间,可以互相借用对方的空间。

Spark1.6 以上版本默认使用的是统一内存管理,可以通过参数spark.memory.useLegacyMode 设置为 true (默认为 false)使用静态内存管理。

  1. 静态内存管理分布图在这里插入图片描述
  2. 统一内存管理分布图在这里插入图片描述
  3. reduce 中 OOM 如何处理?
  1. 减少每次拉取的数据量
  2. 提高 shuffle 聚合的内存比例
  3. 提高 Excutor 的总内存

Shuffle 调优

  1. SparkShuffle 调优配置项如何使用?

1) 在代码中,不推荐使用,硬编码。

new SparkConf().set(“spark.shuffle.file.buffer”,”64”)

2) 在提交 spark 任务的时候,推荐使用。

spark-submit --conf spark.shuffle.file.buffer=64 –conf ….

3) 在 conf 下的 spark-default.conf 配置文件中,不推荐,因为是写死后所有应用程序都要用。

  1. Shuffle 调优附件
    在这里插入图片描述

本节作业

  1. Spark 广播变量和累计器代码敲一遍。
  2. Spark SortShuffleManager 流程?
  3. Spark Shuffle文件寻址过程?
  4. Spark统一内存分配?
  5. Spark Shuffle优化参数?
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页