跟我一起学【Spark】之——Spark调优与调试

第8章 Spark调优与调试

1.总结Spark的配置机制

2.理解Spark应用性能表现的基础知识、设置相关配置项、编写高性能应用设计模式

3.探讨Spark的用户界面、执行的组成部分、日志机制

8.1使用SparkConf配置Spark

1.SparkConf实例包含用户要重载的配置选项的键值对。

Spark中的每个配置选项都是基于字符串形式的键值对。

调用set()方法来添加配置项的设置。

#创建一个conf对象
conf = new SparkConf()
conf.set("spark.app.name","My Spark App")
conf.set("spark.master","local[4]")
conf.set("spark.ui.port","36000")#重载默认端口配置
#使用这个配置对象创建一个SparkContext
sc = SparkContext(conf)

2.动态地为给定应用 设置配置选项

通过spark-submit工具动态设置,当应用被spark-submit脚本启动时,脚本会把这些配置项设置到运行环境中。

当一个新的SparkConf被创建出来时,这些环境变量会被检测出来并自动配置好。

于是乎~在使用spark-submit时,用户应用中只要创建一个“空”的SparkConf,并直接传给SparkContext的构造方法就OK了。

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-default.conf文件,尝试读取该文件中以空格隔开的键值对数据。

同样!使用spark-submit的 --properties-File标记,自定义该文件的路径

优先级:

最高:用户代码中显式调用set()方法设置的选项。

其次:通过 spark-submit 传递的参数

再次:写在配置文件中的值,

最后:系统的默认值

ps:在应用的网页用户界面查看 实际生效的配置。

8.2Spark执行的组成部分:作业、任务和步骤

8.3查找信息

8.3.1Spark网页用户界面

  如果是在TARN集群模式来说,需要通过Yarn的资源管理器来访问用户界面。Yarn的资源管理器会把请求直接转发给驱动器程序

1.作业页面:步骤与任务的进度和指标

包含正在进行或刚完成不久的Spark作业的详细执行情况。

着眼于组成作业的所有步骤,看看是不是有一些步骤特别慢,或是在多次运行同一个作业时响应时间差距很大。

如果有,就点击进去来更好的理解该步骤对应的是哪段用户代码。再借助下图所示的步骤来定位性能问题

在Spark这样的并行数据系统中,数据倾斜是导致性能问题的常见原因之一。

当看到少量的任务相对于其他任务需要花费大量时间的时候,一般就是发生了数据倾斜。

从任务的运行时间开始看,发现时长较大的,

是不是读取或者输出了比别的任务多得多的数据?

是不是运行在某些特定节点上的任务特别慢?

本页面还可以用来查看任务在其生命周期的各个阶段(读取、计算、输出)分别花费了多久。

有些任务肯能把时间基本都花在从外部存储系统中读取数据这部分,这样为Spark作额外的优化对于提高性能就没有多大用处了,毕竟这些任务的瓶颈在于输入数据的读取。

2.存储页面:已缓存的RDD的信息

当有人在一个RDD上调用了persist()方法,并且在某个作业中计算了该RDD时,这个RDD就会被缓存下来。

RDD会有新老替换机制(从内存中移除)。

这个页面可以告诉我们到底各个RDD的哪些部分被缓存了,以及在各种不同的存储媒介中所缓存的数据量。

3.执行器页面:应用中的执行器进程列表

查询异常的执行器节点,例如某个节点有很高的失败率,查看他是否是因为主机的配置问题。

执行器页面的另一个功能是使用线程转存(Thread Dump)按钮收集执行器进程的栈跟踪信息。这种信息分析可以检测出低效的用户代码。

4.环境页面:用来调试Spark配置项

枚举Spark应用所运行的环境中实际生效的配置项集合

当你检查哪些配置标记生效时,这个界面很有用,尤其当使用了多种配置机制时。

此页面同样会列出你添加到应用路径中的所有Jar包和文件,在追踪类似依赖缺失的问题时可以用到。

8.3.2驱动器进程和执行器进程的日志

查看内部警告以及用户代码输出的详细异常信息,需要深入研读驱动器进程和执行器进程所产生的日志。

Spark日志文件的位置取决于部署模式:

Spark独立模式,所有日志会在独立模式主节点的网页用户界面中直接显示。

Mesos模式下,日志存储在Mesos从节点的work/目录中,可以通过mesos主节点用户界面的访问。

Yarn模式下,最简单的收集日志的方法是使用YARN的日志收集工具(运行Yarn logs -applicationId <app ID> 来生成一个包含应用日志的报告。这种方法只有在应用已经完全完成之后才能使用,因为YARN必须先把这些日志聚合到一起。)

要查看当前运行在YARN上的应用日志,可以从资源管理器的用户界面点击进入节点(Node)页面。

日志位置在conf/log4j.properties.template。要想自定义Spark日志,首先需要把示例文件赋值为log4j.properties,然后修改日志行为。例如修改日志等级,默认为INFO

 

8.4关键性能考量

8.4.1并行度

    Spark会针对RDD直接自动推断出合适的并行度。

    当并行度过低时,Spark集群会出现资源闲置的情况。

    当并行度过高时,每个分区产生的间接开销累计起来就会更大。

    评判并行度是否过高的标准:任务是否是几乎在瞬间(毫秒级)完成的;观察到任务没有读写任何数据。

    Spark提供的两种并行度调优方法:

  1.   数据混洗时,使用参数为混洗后的RDD指定并行度;
  2.   对任何已有的RDD,进行重新分区来获取更多或更少的分区数。

8.4.2序列化格式

    Spark支持第三方序列化库Kryo,但是不能直接序列化全部类型的对象。

    使用Kryo,需要设置spark.serializer 为 org.apache.spark.serializer.KryoSerializer.

    为了获得最佳性能,还应该向Kryo注册想要序列化的类。注册类可以让Kryo避免把每个对象的完整的类名写下来。

    如果想强制要求这种注册,可以把spark.kryo.registrationRequired设置为true,这样Kryo会在遇到未注册的类时抛出错误。

    如果代码中引用了一个没有扩展的Java的Serializable接口的类,会遇到NotSerializableException。

8.4.3内存管理

    内存的用途:RDD存储、数据混洗与聚合的缓存区、用户代码

    默认情况下,Spark会使用60%的空间来存储RDD,20%存储数据混洗操作产生的数据,20%留给用户程序。

    memory_only()的存储等级,如果缓存新的RDD分区时空间不够,旧的分区就会直接被删除,当用到这些分区数据时,再重算

    memory_and_disk的存储等级调用persist()方法,内存中放不下的旧分区会被写入磁盘,当再次需要用到的时候再从磁盘上读取回来。(适用场景:当RDD分区的重算代价很大(比如从数据库中读取数据时))

    memory_only_ser或者memory_and_disk_ser实现缓存序列化后的对象而非直接缓存。,可以显著减少JVM的垃圾回收时间。

8.4.4硬件供给

影响集群规模的主要参数:

  • 分配给每个执行器节点的内存大小
  • 每个执行器节点占用的核心数
  • 执行器节点总数
  • 存储临时数据的本地磁盘数量

出处:《Spark快速大数据分析》作者:Holden Karau

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值