<Spark><Tuning and Debugging>
Overview
- 这一部分我们主要讨论如果配置一个Spark application,如何tune and debug Spark workloads
- 配置对Spark应用性能调优很重要。我们有必要理解一个Spark应用的性能。
Configuring Spark with SparkConf
- 我们知道,在创建SparkContext的时候会需要SparkConf实例。一个例子:
val conf = new SparkConf()
.setAppName("Test")
.setMaster("local")
val sc = new SparkContext(conf)- SparkConf类很简单,包含一些用户可覆盖的配置选项的键值对
- 也可以通过spark-submit动态地设置配置。基于这种方法,你可以在程序中new一个“空”的SparkConf,直接传给SparkContext。这种方式下可以直接使用 --conf标记,该标记之后可以使用任何Spark配置值。例子:
bin/spark-submit \
--class com.wtttt.spark.test \
--master local \
--name "test" \
--conf spark.ui.port=36000 \
test.jar- 这种spark-submit的方式除了可以使用--conf,还可以从文件加载。缺省情况下,spark-submit会在conf/spark-defaults.conf中读取whitespace-delimited 的键值对。你也可以使用
--properties-file 来指定conf文件。例子:
bin/spark-submit \
--class com.wttttt.spark.test \
--properties-file my-config.conf \
test.jar## Contents of my-config.conf ##
spark.master local[4]
spark.app.name "test"
spark.ui.port 36000 - 如果多处同时设置的话,程序设置的优先级高于spark-submit指定的。
- 完整的conf选项参考 spark configuration。
Components of Execution: Jobs, Tasks, and Stages
- 我们知道,Spark会把逻辑表示翻译成一系列物理执行计划,by merging multiple operations into tasks.
- 看下面的例子:
val input = sc.textFile("input.txt") val tokenized = input.
map(line => line.split(" ")).
filter(words => words.size > 0) val counts = tokenized.
map(words => (words(0), 1)).
reduceByKey{ (a, b) => a + b} // example of the source file "input.txt"
## input.txt ##
INFO This is a message with content
INFO This is some other content
(empty line)
INFO Here are more messages
WARN This is a warning
(empty line)
ERROR Something bad happened
WARN More details on the bad thing
INFO back to normal messages - 当我们在shell输入上述语句之后,并不会执行任何actions,只会隐式地定义一个DAG(有向无环图)。我们可以用toDebugString来看看:
scala> counts.toDebugString
res84: String =
(2) ShuffledRDD[296] at reduceByKey at <console>:17
+-(2) MappedRDD[295] at map at <console>:17
| FilteredRDD[294] at filter at <console>:15
| MappedRDD[293] at map at <console>:15
| input.text MappedRDD[292] at textFile at <console>:13 | input.text HadoopRDD[291] at textFile at <console>:13- 我们执行一个action来触发计算: counts.collect()
- 这时,Spark的调度器scheduler会创建一个物理执行计划来计算该action所需的RDDs(递归地向前找所有需要的RDDs)。
- 更复杂的情况是,stages的物理集合不是与RDD graph 1:1对应的。这种情况发生在scheduler执行pipelining或者合并多个RDDs到一个stage的时候。pipelining发生在RDDs可以从parents本地计算的时候(不需要data movement)。
- 对于上面的例子,计算counts的时候,即使counts有很多个parent RDDs,它也只存在two levels of indentation。所以它的物理执行只需要两个stages。该例中的pipelining就是因为有多个filter和map的序列。如下图:

- 运行这个action,看spark UI: 一共一个job,两个stages。
- Completed Jobs (1)

Completed Stages (2)

- 除了pipelining,Spark内部的scheduler也会在有RDD已经被persisted到内存或磁盘的时候缩短RDD graph的lineage。
- 还有一种(可缩短lineage的)情况是,RDD已经通过之前的shuffle被materialized到磁盘。即使没有显式地调用persist()。这种情况是充分利用了shuffle的输出会写到磁盘的特点。
- 做个实验:
counts.cache()
counts.collect()看下这个job的stages:

可以看到只执行了一个stage,另一个被skip了。
- 以上,Spark执行的时候包括这么几个阶段:
- User code定义一个RDD的DAG;
- Actions force DAG到执行计划的translation;这时Spark调度器提交一个job来计算所有所需的RDDs。该job会有一或多个stages,它们是由task组成的并行计算浪潮(parallel waves of computation composed of tasks)。由于pipelining,每个stage可以对应多个RDDs。
- Tasks被调度,在集群上执行;stages按顺序执行,individual tasks执行RDD的各个部分。
Finding Information
- 具体的进度信息、性能度量可以在Spark web UI以及driver和executor的logfiles中找到。
Spark Web UI
- 说明:YARN cluster模式下,application driver是运行在cluster内部的,因此你需要通过YARN resourceManager来访问UI。
Jobs: Progress and metrics of stages, tasks, and more
- 一般首先是点进去一个比较慢的stage,其内部可能存在skew,因此你可以看下是否某些tasks运行时间过长。比如你可以看是否这些tasks read, write or compute much more than others?
- 你还可以看每个task读、计算、写分别占用的时间。如果tasks花很少时间读写,那么可能user code本身是expensive的,作为solution之一你可以参考advanced programming中提到的"Working on a Per-Partition Basis"来减少比如创建对象的开销。 但是如果tasks花费很多时间来从外部系统读取数据,那么可能不存在更多的外部优化方式。
Storage: Information for RDDs that are persisted
- storage页面包含了persisted RDDs的信息。
- 通常,如果很多RDDs都会缓存的话,older ones可能会被移除。
Executors: A list of executors present in the application
- 该页列出了应用中活跃的executors,以及每个executor在处理和存储中的一些度量。
- 这一页的用处是你可以确认你的application拥有你所预期的资源。
Environment: Debugging Spark's configuration
This page enumerates the set of active properties in the environment of your Spark application.
Driver and Executor logs
- YARN模式下,最简单的收集日志的方式是使用YARN日志收集工具
(running yarn logs -applicationId <app ID>)
<Spark><Tuning and Debugging>的更多相关文章
- 简单物联网:外网访问内网路由器下树莓派Flask服务器
最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...
- 利用ssh反向代理以及autossh实现从外网连接内网服务器
前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...
- 外网访问内网Docker容器
外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...
- 外网访问内网SpringBoot
外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...
- 外网访问内网Elasticsearch WEB
外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...
- 怎样从外网访问内网Rails
外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...
- 怎样从外网访问内网Memcached数据库
外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...
- 怎样从外网访问内网CouchDB数据库
外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...
- 怎样从外网访问内网DB2数据库
外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...
- 怎样从外网访问内网OpenLDAP数据库
外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...
随机推荐
- CentOS7.3将网卡命名方式设置为传统方式
CentOS7.3将网卡命名方式设置为传统方式 生产环境可能拥有不同系列的操作系统,比如,既有CentOS6系列,也有CentOS7系列的系统,而CentOS6和CentOS7在网卡命名方面有着较大区 ...
- 31. Next Permutation (java 字典序生成下一个排列)
题目: Implement next permutation, which rearranges numbers into the lexicographically next greater per ...
- Single Number III leetcode java
问题描述: Given an array of numbers nums, in which exactly two elements appear only once and all the oth ...
- 『流畅的Python』第10章笔记_序列类型
一.基础知识 “__”前缀:私有属性.方法,在__dict__中存储时被改写为“_类名__”前缀 “_”前缀:是约定俗成的保护属性.方法,不过编译器不会对之采取任何处理 二.class特殊方法介绍 在 ...
- 『OpenCV3』Mat简介
Mat属性方法介绍:OpenCV2:Mat属性type,depth,step 推荐一套OpenCV入门博客:OpenCV探索 一.Mat Mat类用于表示一个多维的单通道或者多通道的稠密数组.能够用来 ...
- java中String创建对象分析(转)
String str=new String("abc"); 紧接着这段代码之后的往往是这个问题,那就是这行代码究竟创建了几个String对象呢? 相信大家对这道题并不陌生,答案 ...
- 移动端页面利用好viewport,适配各种宽度屏幕
最近研究微贷网的移动端代码,发现他们网站在适配不同宽度屏幕的显示情况时,发现他们并不是利用rem单位,而是利用js动态设置mete的viewport来达到适配的效果. 感觉挺不错的,也不需要计算什么东 ...
- Script to Collect Log File Sync Diagnostic Information (lfsdiag.sql) (文档 ID 1064487.1)
the article from :http://m.blog.itpub.net/31393455/viewspace-2130875/ Script to Collect Log File Syn ...
- Python print打印
1.Python运算符: +:加 -:减 *:乘 /:除以 %:去除法后的余数 //:取整除 2.字符串center方法: a='111'print(a.center(4,'2')) #让字符串占位 ...
- MySQL变量变更小记
MySQL会随版本的更新,在新版本中淘汰一些variable和引入一些新的variable.在配置variable后不起作用或安全扫描取不到variable值产生告警时,可能正是variable变更的 ...