监控Spark应用有很多种方法。
Web接口
每一个SparkContext启动一个web UI用来展示应用相关的一些非常有用的信息,默认在4040端口。这些信息包括:
任务和调度状态的列表
RDD大小和内存使用的统计信息
正在运行的executor的信息
环境信息
你可以在浏览器中打开http://<driver-node>:4040网址来访问这些信息。如果在同一台机器上有多个SparkContext正在运行,那么他们的端口从4040开始依次增加(4041,4042等)。
Spark在单机模式下也提供了web UI。
注意,在所有这些web接口可以通过点击“表头”来对这些表格进行排序。这使得鉴别运行速度慢的任务、判别数据倾斜等非常容易。
Metrics
Spark基于Coda Hale Metrics库提供一个可配置的统计系统。这允许用户向不同的终端发送统计信息,包括HTTP、JMX和CSV文件。统计系统可以通过配置文件来进行配置,Spark默认将配置文件保存在$SPARK_HOME/conf/mertics.conf。用户可以通过Java property spark.metrics.conf来修改配置文件的保存路径。Spark根据组件的不同将统计信息分为多个实例。可以配置每一个实例向多个方向发送统计信息。目前支持下面几种实例:
master:Spark管理进程
applications:位于master的组件,统计发送各种应用的信息
worker:Spark工作进程
executor:执行器
driver:Spark驱动程序
每一个实例可以向多个渠道发送统计信息。渠道包含在包org.apache.spark.metrics.sink:
ConsoleSink:将统计信息发送到控制台
CSVSink:每隔一段时间将统计信息写入到CSV文件
GangliaSink:将统计信息发送到Ganglia或者多播组
JmxSink:将统计信息注册到JMX控制台
MetricsServlet:在Spark UI中添加servlet用来以JSON的方式提供统计信息
统计信息配置文件的语法有一个示例文件——$SPARK_HOME/conf/metrics.conf.template.
外部工具
有几个外部工具可用来衡量Spark作业的性能:
集群范围的监控工具,比如 Ganglia,可以洞察整个集群的利用率和资源瓶颈。例如,Ganglia仪表盘可以迅速揭示出某个特定载荷是磁盘相关,网络相关,还是CPU相关的。
OS性能分析工具,比如 dstat, iostat,和 iotop, 可以提供各个节点的细粒度的分析。
JVM工具,比如 jstack提供了堆栈跟踪,jmap提供了创建堆转储,jstat提供了时间序列统计报告,还有jconsole提供了各种JVM属性的视觉显示,它们对JVM内部构件的舒适运作都是非常有用的。
讨论Spark的配置监控和性能优化(某课程笔记)
上完这节课以后,你将能够描述集群的概念
通过修改Spark的属性,环境变量,或者是日志属性来配置Spark
使用Web端界面,以及各种不同的外部工具来监控Spark和应用程序
在Spark集群中有三种主要的组成部分。驱动程序,是放置主程序中SparkContext的地方,要运行一个集群,你需要一个集群管理器
它可以是单机版的集群管理器,也可以是 Mesos 或者 Yarn
而worker节点,就是放置执行器的地方
执行器,是运行计算和储存应用程序数据的地方。SparkContext以JAR或者Python文件
的形式向每个执行器发送应用程序。最终,它向每个执行器发送任务并运行
因为驱动程序在集群上调配任务,它应该在相同的本地网络中
的woker节点运行。如果要向集群发送远端请求
最好使用一个RPC,并且从附近的节点提交操作
我们前面提到三个支持的集群管理器
对于Spark的配置,主要有三个主要的地方
Spark属性,你可以用SparkConf对象或者通过Java系统属性来设置应用程序的参数
环境变量,你可以用它们来设置每一个机器的设定,比如IP地址这是通过配置每一个节点上的conf/spark-env.sh脚本实现的
对于日志属性,它可以通过log4j.propertieis来进行设置
你可以选择修改目前位于SPARK_HOME/conf目录下的默认配置目录设定SPARK_CONF_DIR环境变量并且在这个目录下提供你的配置文件
这里有两种方法来设定Spark属性:
第一种方法是通过SparkConf对象来传递应用程序属性
第二种方法是动态地设置Spark的属性。Spark允许你在创建一个SparkContext的时候传递一个空的SparkConf
然后,在运行时用 “—master” 或者 “—conf” 参数命令行选项来提供设置值
你可以运行spark-submit脚本的时候,通过“—-help”来查看各种选项
另一种设定Spark属性的方法是在spark-defaults.conf文件里设置
spark-submit脚本会从你的文件中读取这些配置
你可以在应用程序的默认端口为4040的Web客户端上查看Spark属性
最后我想提到的一件注意事项,直接SparkConf上设置的属性具有最高的优先级
spark-submit或者spark-shell是第二优先级,最后是spark-default.conf文件里的设置。
监控Spark应用程序有三种方法:第一种方法是使用基于Web的客户端,它的默认端口是4040
在应用程序运行期间,你可以在这个客户端上获得Spark实时监控信息
如果你希望在程序运行完以后查看这些信息,你需要在应用程序开始之前把spark.eventlog.enabled属性设定为true,这样所有运行的信息就会被储存起来
Metrics是另一种检测Spark应用程序的方法。这个metric系统是基于Coda Hale Metrics库的
你可以自定义输出的格式,例如CSV格式的运行报告
可以在conf目录下的metrics.properties文件中配置metrics系统
最后,也可以通过外部工具来监控Spark。例如,Gangalia是用来查看整体集群的利用情况和资源瓶颈的工具。
各种不同的OS profiling工具和JVM工具也可以用来监测Spark
默认设置下,Web客户端可以在端口4040下查看,它显示当前
正在运行的应用程序的信息。Web客户端,可以看到任务协调器的状态,提交的任务状态,RDD的大小,内存使用量的报告,环境设置信息以及
正在运行的执行器的信息
要在应用程序运行完以后查看应用程序的历史,你需要启动历史记录服务器配置历史记录服务器可以规定给它分配多少内存
各种JVM的选项,服务器的公共地址以及一系列的属性
集群中的任何一种资源都有可能成为Spark的瓶颈
Spark的内存计算属性,数据序列化以及内存优化成为能够提升Spark效能的
两个主要的因素。
数据的序列化是一种提升网络效能并减少内存使用的关键这是当你要优化Spark应用程序需要优先考虑的
Spark提供两个数据序列化的库。Java序列化提供更多的选择,但是它们通常很慢
而且生成过大的序列化对象。但这个是Spark用来序列化对象的默认库
Kyro序列化比Java要快很多,但是不支持所有的序列化类型
你需要提前注册这些类库,来获得最好的性能效果,可以通过设置SparkConf对象来使用Kyro序列化
在内存优化中,你需要考虑三件事:
1)对象使用的内存有多少(无论你是否想将全部对象导入到内存中);
2)获取这些对象的成本;
3)垃圾回收的管理费用
你创建一个RDD,先将它缓存,然后查看你驱动程序中的
SparkContext日志。查看日志可以帮助你了解数据集需要多少内存
这里有减少每个对象内存使用量的一些建议。尽量避免增加管理费用的某些Java特征
比如基于指针的数据结构和wrapper对象。如果可以的话,使用数组或者原始数据类型并且避免使用迭代结构
序列化储存也可以帮助减少内存使用。缺点是它会导致要花更多的时间来获取数据
因为在你使用这些数据之前,你必须要对它们进行反序列化
你可以在垃圾回收器中查看它发生的频率,以及它使用时间的、一系列指标。你可以通过将此行增加到SPARK_JAVA_OPTS环境变量中来实现它
为了要充分利用集群,并行的级别也是需要考虑的因素之一
它自动地被设置为任务文件的大小,但是你可以通过例如在SparkContext.textFile里的
选项参数来配置它。你也可以对spark.default.parallelism的config属性设置默认的并行级别。通常来说,我们建议在集群中
为每一个CPU核设置2到3个任务
当你的内存不能容纳你的RDD的时候,你会得到一个OutOfMemoryError错误
在这种情况下,通过提升并行级别可以解决这个问题
通过提升并行级别,每一个输入的任务集都会变得更小,这样内存就可以容纳了
通过Spark的广播变量的功能,可以极大地减小序列化对象的大小
有一个比较好的例子,比如你有某种静态的公共查询表
考虑一下把它变成一个广播变量,这样它就不需要被发送到
每一个worker节点上,省去了很多序列化对象的工作
Spark将每一个任务序列化之后的大小打印到主节点上。通过查看这些信息,
也可以帮助检查否有任务过大。如果你发现某些任务超过20KB,你就有必要考虑
是否需要对它进行优化,比如创建广播变量
Spark1.0.0可以通过以下几种方式来对Spark应用程序进行监控:
- Spark应用程序的WebUI或者Spark Standalone的集群监控
- 指标,然后通过支持指标收集的集群监控系统,如ganglia进行监控
- 辅助监控工具
1:WebUI
Spark应用程序提交后,driver和Executor之间不断的交换运行信息,可以通过driver的4040端口(默认端口)获取有用的Spark应用程序的运行信息,如:
- Stage和Task
- RDD大小和内存使用情况
- 环境变量信息
- executor的运行信息
- ...
如果多个Spark应用程序在同一个client上以client方式提交,那么driver的WebUI端口将绑定从4040开始的连续端口,如4040、4041、4042...。
需要注意的是,用过WebUI只能查看Spark应用程序在运行期间的信息,一旦Spark应用程序运行完,这些信息将无法查看,因为WebUI端口随Spark应用程序的完成而关闭。如果想要事后查看Spark应用程序的运行信息,那么需要配置history Server来持久化Spark应用程序运行信息。关于history Server参见Spark1.0.0 history server配置(正在撰写,迟点给上链接) 。
2:指标
Spark采用了基于Coda Hale Metrics Library 的可配置的指标体系,通过各种指标收集器,如JMX、CSV、GraphiteSink、Ganglia等可以进行汇总报告。该指标体系的配置文件位于conf/metrics.properties(通过复制conf/metrics.properties.template生成或自建),如果要采用自定义的配置文件,还需要在属性配置上配置一下spark.metrics.conf。
Spark的指标体系针对Spark不同的组件分解成相应的实例,每个实例涵盖一套指标。Spark现在支持的实例有:
- master
- worker
- applications
- driver
- executor
Spark的指标体系支持多种收集器,每个实例可以采用多个收集器,也可以不采用。Spark支持的收集器定义在org.apache.spark.metrics.sink,现在支持的收集器有:
- ConsoleSink
- CSVSink.
- JmxSink
- MetricsServlet
- GraphiteSink
- GangliaSink 因为版权问题,部署包默认不含有该收集器;如果需要,要重新编译嵌入LGPL授权代码的源码。具体使用参见用ganglia监控Spark1.0.0(正在撰写,迟点给上链接)。
3:辅助监控工具
可以通过一些辅助监控工具对Spark应用程序运行前后和运行过程中系统性能变化来监控Spark应用程序。这些辅助工具有:
- 集群监控系统,如ganglia、negios、zabbix等,这些工具可以监控整个集群的磁盘、网络、内存利用率和性能瓶颈;
- 操作系统性能分析工具,如dstat、iostat、iotop,这些工具可以对单台机器的性能进行细致地分析;
- JVM性能分析工具,如 jstack、jmap、jstat 、jconsole,这些工具可以对JVM进行详细的性能分析。