小白学习Spark04-Spark调优与调试

4.1 使用SparkConf配置Spark
  • 三种方式配置SparkConf的值
    • 在代码中修改
      • 通常可以通过修改Spark应用的运行时配置选项对Spark进行性能调优,在Spark中最主要的配置机制是通过SparkConf类对Spark进行配置。
       	//在Scala中使用SparkConf创建一个应用
       	//创建一个conf对象
      	val conf = new SparkConf()
      	conf.set("spark.app.name","My Spark App")
      	conf.set("spark.master","local[4]")
      	conf.set("spark.ui.port","36000") // 重载默认端口配置
      	
      	// 使用这个配置对象创建一个SparkContext
      	val sc= new SparkContext(conf)
      
      • SparkConf实例包含用户要重载的配置选项的键值对,Spark中的每个配置选项都是基于字符串形式的键值对。
      • 使用创建出来的SparkConf对象,可以调用set()方法来添加配置项的设置,然后把这个对象传给SparkContext的构造方法。
    • 通过spark-submit工具动态设置配置项
      • 当应用被spark-submit脚本启动时,脚本会把这些配置设置到运行环境中。
      • spark-submit 工具为常用的Spark配置项参数提供专用的标记,还有一个通用标记 --conf来接收任意Spark配置项的值
       	//在运行时使用标记设置配置项的值
       	$ bin/spark-submit --class com.example.MyApp --master local[4] --name "My Spark App" --conf spark.ui.port=36000 myApp.jar
      
    • spark-submit 也支持从文件中读取配置项的值
      • 方便不同用户共享这些配置
      • spark-submit 脚本会在Spark安装目录中找到conf/spark-defaults.conf文件,尝试读取该文件中以空格隔开的键值对数据。也可以通过spark-submit的–properties-File标记,自定义该文件的路径。
       	//在运行时使用默认文件设置配置项的值
       	$ bin/spark-submit --class com.example.MyApp --properties-file my-config.conf myApp.jar
      
    • Spark特定优先级顺序来选择实际配置:用户代码 -> spark-submit传递的参数 ->写在配置文件的值 -> 系统的默认值
    • 常用的Spark配置项的值
      在这里插入图片描述
      在这里插入图片描述
    • 几乎所有的Spark配置发生在SparkConf的创建过程中,有一个例外:在conf/spark-env.sh 中将环境变量SPARK_LOCAL_DIRS设置为用逗号隔开的存储位置列表,来指定Spark用来混洗数据的本地存储路径,这需要在 独立模式 和 Mesos模式 下设置。
4.2 Spark执行的组成部分:作业、任务和步骤
  • Spark将多个操作合并为一组任务,把RDD的逻辑表示翻译为物理执行计划。
  • RDD在各种转化操作下,会定义为一个RDD对象的有向无环图(DAG),每个RDD都维护了其指定一个或多个父节点的 引用 来表示其与父节点之间关系的信息,这些 引用 可以追踪其所有的祖先节点(toDebugString()方法可以查看RDD的谱系)
  • 在调用行动操作之前,RDD都只是存储着可以让我们计算出具体数据的描述信息。
  • Spark调度器会从最终被调用行动操作的RDD出发,从上回溯所有必须计算的RDD,调度器会访问RDD的父节点、父节点的父节点,以此类推,递归向上生成计算所有必要的祖先RDD的物理计划。
  • 最简单的情况:调度器为有向图中的每个RDD输出计算步骤,步骤中包括RDD上需要应用于每个分区的任务,然后以相反的顺序执行这些步骤,计算出最终所求的RDD。
  • 复杂的情况:调度器是进行流水线执行(pipelining)或把多个RDD合并到一个步骤中,当RDD不需要混洗数据就可以从父节点计算出来,调度器就会自动进行流水线执行,此时RDD图与执行步骤的对应关系并不一定是一一对应的。
  • 将RDD转化操作串联成物理执行的步骤
    在这里插入图片描述
  • 上图输出的谱系图使用 不同缩进等级来展示 RDD是否会在物理步骤中进行流水线执行,在物理执行时,执行计划输出的缩进等级与其父节点相同的RDD会与其父节点在同一个步骤中进行流水线执行。计算counts时,尽管有很多级父RDD,但从缩进来看总共只有两级,这表明物理执行只需要两个步骤。
  • 通过用户界面(4040端口)可以查看详细信息
  • 除了 流水线执行的优化,当一个RDD已经缓存在集群内存或磁盘上,Spark的内部调度器也会自动截短RDD谱系图。这种内部优化是基于Spark数据混洗操作的输出均被写入磁盘的特性,同时也充分利用了RDD图的某些部分会被多次计算的事实。
  • 特定的行动操作所生成的步骤的集合都被称为一个作业
  • 一旦步骤图确定下来,任务就会被创建出来并发给内部的调度器,改调度器在不同的部署模式下会有所不同,物理计划中的步骤会依赖于其他步骤,步骤也会以特定的顺序执行。
  • 一个物理步骤会启动很多任务,每个任务都是在不同的数据分区上做同样的事情,任务内部流程都是一样的
    • 从数据存储(如果该RDD是一个输入RDD)或已有RDD(如果该步骤是基于已经缓存的数据)或数据混洗的输出中获取输入数据
    • 执行必要的操作来计算出这些操作所代表的RDD
    • 把输出写到一个数据混洗文件中,写入到外部存储,或者是发回驱动器程序
  • Spark的大部分日志信息和工具都是以步骤、任务或数据混洗为单位的。
  • Spark执行的大致流程
    • 用户代码定义RDD的有向无环图
      • RDD上的操作会创建出新的RDD,并引用它们的父节点,这样就创建出来一个图
    • 行动操作把有向无环图强制转译为执行计划
      • Spark调度器提交一个作业来计算所有必要的RDD,则这个作业就会包含一个或多个步骤,每个步骤其实也就是一波并行执行的计算任务。一个步骤对应有向无环图中的一个或多个RDD,一个步骤对应多个RDD是因为发生了流水线执行。
    • 任务于集群中调度并执行
      • 步骤是按顺序处理的,任务则独立地启动来计算出RDD的一部分。
  • 在一个给定的Spark应用中,由于需要创建一系列新的RDD,因此上述阶段会连续发生很多次。
4.3 查找信息
4.3.1 Spark网页用户界面
  • Spark内建的网页用户界面 是了解Spark应用的行为和性能表现的第一站。
  • 用户界面可分为:
    • 作业页面(Jobs):步骤和任务的进度和指标,以及更多内容。包含 正在进行的或刚完成不久的Spark作业的详细执行情况。其中重要信息包括:正在运行的作业、步骤以及任务的进度情况。
    • 步骤页面(Stages):定位性能问题。在Spark等并行数据系统中,数据倾斜是影响性能常见的问题之一。
      • 数据倾斜:当少量的任务相对于其它的任务需要花费大量时间的时候,一般都是发生了数据倾斜。通过查看所有任务各项指标的分布情况来查看是否发生了数据倾斜。
    • 存储页面(Storage):包含缓存下来的RDD信息。浏览这个页面也可以看到一些重要的数据集是否被缓存在了内存中。
    • 执行器页面(Executors):本页面列出了应用中申请到的执行器实例以及各执行器进程在数据处理和存储方面的一些指标。两个用处:
      • 它可以确认应用是否可以使用你所预期使用的全部资源量。
      • 线程转存(Thread Dump)按钮收集执行器的栈跟踪信息,可以检测出低效的用户代码。
    • 环境页面(Environment):用来调试Spark配置项。本页面枚举了你的Spark应用所运行的环境中实际生效的配置项集合。
4.3.2 驱动器进程和执行器进程的日志
  • 日志会更详细地记录各种异常事件。Spark日志文件的具体位置取决于以下部署模式:
    • 在Spark独立模式下,所有日志会在独立模式主节点的网页用户界面中直接显示。这些日志默认存储于各个工作节点的Spark目录下的word/目录中。
    • 在Mesos模式下,日志存储在Mesos从节点的work/目录中,可以通过Mesos主节点用户界面访问
    • YARN模式下,收集日志的最简单方法就是使用YARN的日志收集工具来生成一个包含应用日志的报告。要查看当前运行在YARN上的应用的日志,可以从资源管理器的用户界面点击进入节点(Nodes)页面,然后浏览特定的节点,再动那里找到特定的容器。YARN会提供对应容器中Spark输出的内容以及相关日志。
  • 我们可以自定义日志行为,改变日志的默认等级或者默认存放位置,Spark的日志系统是基于广泛使用的Java日志库log4j实现的,使用log4j的配置方式进行配置。
4.4 关键性能考量
4.4.1 并行度
  • RDD的逻辑表示其实是一个对象集合,在物理执行期间,RDD会被分为一系列的分区,每个人去都是整个数据的子集。当Spark调度并运行任务时,Spark会为每个分区中的数据创建出一个任务。该任务在默认情况下会需要集群中的一个计算核心来执行。Spark会针对RDD直接自动推断出合适的并行度,输入的RDD一般也会根据其底层的存储系统选择并行度。
  • 并行度通过两方面影响程序的性能
    • 当并行度过低时,Spark集群会出现资源闲置的情况
    • 当并行度过高时,每个分区产生的间接开销累计起来就会更大
    • 评判并行度的是否过高的标准包括任务是否是几乎在瞬间(毫秒级)完成的或者是否观察到任务没有读写任何数据。
  • Spark提供两种方法对操作的并行度进行调优
    • 在数据混洗操作时,使用参数的方式为混洗后的RDD指定并行度
    • 对于任何已有的RDD,可以进行重新分区来获取更多或者更少的分区数。重新分区通过repartition(),该操作会把RDD随机打乱并分为设定的分区数目。如果要确定减少RDD分区,优先选择coalesce()操作。
4.4.2 序列化格式
  • 当Spark需要通过 网络传输数据,将数据溢写到磁盘上时,Spark需要把数据序列化为二进制。
  • 序列化会在数据进行混洗操作时发生,因此有可能需要通过网络传输大量的数据。
  • 默认情况下,Spark会使用Java内建的序列化库。
4.4.3 内存管理
  • 默认情况下,Spark会使用60%空间来存储RDD,20%存储数据混洗操作产生的数据,剩下的20%留给用户程序。
    • RDD存储:当调用RDD的persis()或cache()方法时,这个RDD的分区会被存储到缓存区中,Spark会根据spark.storage.memoryFraction限制用来缓存的内存占整个JVM堆空间的比例大小,若超出限制,则旧的分区数据会被移出内存。
    • 数据混洗和聚合的缓存区:当进行数据混洗时,Spark会创建出一些中间缓存区来存储数据混洗的输出数据。这些缓存区用来存储聚合操作的中间结果以及数据混洗操作中直接输出的部分缓存数据。Spark会尝试根据spark.shuffle.memoryFraction限定这种缓存区总内存的比例。
    • 用户代码:Spark可以执行任意的用户代码,所以用户的函数可以自行申请大量内存。
  • 优化更好性能:
    • 调整内存各区域的比例
    • 为一些工作负载改进缓存行为
    • 缓存序列化后的对象而非直接缓存
4.4.4 硬件供给
  • 影响集群规模的主要参数:
    • 分配给每个执行器节点的内存大小
    • 每个执行器节点占用的核心数
    • 执行器节点总数
    • 以及用来存储临时数据的本地磁盘数量。





  • 关注「一个热爱学习的计算机小白」公众号 ,对作者的小小鼓励,后续更多资源敬请关注。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值