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执行的时候包括这么几个阶段:
    1. User code定义一个RDD的DAG;
    2. Actions force DAG到执行计划的translation;这时Spark调度器提交一个job来计算所有所需的RDDs。该job会有一或多个stages,它们是由task组成的并行计算浪潮(parallel waves of computation composed of tasks)。由于pipelining,每个stage可以对应多个RDDs。
    3. 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>的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. Excel文件的读写

    import xlsxwriter,xlrd import sys,os.path fname = 'zm6.xlsx' if not os.path.isfile(fname): print ('文 ...

  2. python-day81--Ajax

    一.准备知识:json 1.什么是json? JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式.任何的语言之间都可以用json进行数据的交 ...

  3. mysql 全文搜索(转载http://blog.csdn.net/manbujingxin/article/details/6656992)

    前提:mysql只支持英文内容的全文索引,所以只考虑英文的全文搜索.假定数据表名为post,有三列:id.title.content.id是自增长序号,title是varchar,content是te ...

  4. MySQL5.6复制技术(3)-MySQL主从复制线程状态转变

    一.主库线程状态(State)值 以下列表显示了主从复制中主服务器的Binlog Dump线程的State列中可能看到的最常见状态(SHOW PROCESSLIST).如果Binlog Dump线程在 ...

  5. Python迭代和列表生成器

    使用for循环遍历list和tuple,这种遍历成为迭代 在如C语言中都是通过下标拿到值,for...in这种方式其实是相同的. 在函数的一节,这样说--->‘求和函数sum(),sum(ite ...

  6. Mysql for Linux安装配置之—— 源码安装

    1.安装 --假设已经有mysql-5.5.10.tar.gz以及cmake-2.8.4.tar.gz两个源码压缩文件1)先安装cmake(mysql5.5以后是通过cmake来编译的)   # ta ...

  7. composer install Your requirements could not be resolved to an installable set of packages

    composer install --ignore-platform-reqs 或者 composer update --ignore-platform-reqs

  8. php微信公众号开发

    简单的事例总结: wamp下载安装:https://sourceforge.net/projects/wampserver/ www目录里创建php文件weixin.php <?php head ...

  9. PAT-GPLT训练集 L1-043 阅览室

    PAT-GPLT训练集 L1-043 阅览室 注意:连续的S和E才算一次借还 代码: #include<iostream> #include<cstdio> using nam ...

  10. 【框架】用excel管理测试用例需要的参数数据(二)

    一.总体思路 以类为excel名,测试方法名为sheet名,建立excel文件.用jxl包里的方法去读取excel文件里的内容,然后用testng里的dataprovider,将数据传递给测试用例 二 ...