一、总体思路

以上是我在平时工作中分析spark程序报错以及性能问题时的一般步骤。当然,首先说明一下,以上分析步骤是基于企业级大数据平台,该平台会抹平很多开发难度,比如会有调度日志(spark-submit日志)、运维平台等加持,减少了开发人员直接接触生成服务器命令行的可能,从物理角度进行了硬控制,提高了安全性。

下面我将带领大家从零到一,从取日志,到在Spark WebUI进行可视化分析相关报错、性能问题的方法。

二、步骤

(一)获取applicationID

1.从调度日志获取

一般企业级大数据平台会相对重视日志的采集,这不仅有助于事后对相关问题、现象的分析;同时也是相关审计环节的要求。

我们知道,spark的调度是通过spark-submit执行触发的,每一次spark-submit都会有对应的applicationID生成,所以,一般我们可以在调度日志中可以找到本次调度的applicationID。

2.从运维平台获取

企业级大数据平台为了减少开发、运维人员直接通过ftp、putty、xshell等工具直连生产服务器,避免误操作等风险发生,一般会提供一个运维平台,在页面上便可直接查看到job粒度的作业运行情况,以及其唯一标志applicationID,缩短了开发、运维人员获取applicationID的“路径”,减少了机械性的步骤。

(二)从HDFS下载Spark history

我们假设我们的大数据平台把spark history保存到了HDFS的/sparkJobHistory/ 目录下,下面我们来看看具体如何获取我们对应applicationID的spark history。

1.命令行下载HDFS文件

hadoop fs -get /sparkJobHistory/applicationID_xxxxx_1-meta localfile
hadoop fs -get /sparkJobHistory/applicationID_xxxxx_1-part1 localfile

2.HUE工具下载HDFS文件

我们使用租户登录HUE工具,进入到File Browser页面,并通过页面上的目录访问按钮进入到sparkJobHistory目录下,然后在搜索框中输入applicationID ,就可以看到该applicationID对应的spark history(meta和part1两个文件)显示在了页面中,勾选并下载,便可以将spark history下载到我们本地。

(三)上传Spark history到开发环境

接下来我们要做的工作就是将从生产上获取到的spark history放到我们开发环境上,以便进行后续分析。

1.命令行推送spark history到HDFS上

首先我们需要将从生产下载到本地的spark history上传到我们测试环境的任意一个节点上,这里我们将其上传到测试环境01节点的${WORK_ROOT}/etluser/tmp/spark_history/applicationID_xxxxx/路径下,接下来在测试环境命令行执行以下命令,将spark history上传到HDFS:

hadoop  fs -put ${WORK_ROOT}/etluser/tmp/spark_history/applicationID_xxxxx/* /sparkJobHistory/

2.HUE工具上传spark history到HDFS上

这个步骤和我们在生产HUE类似,首先使用租户登录到测试环境HUE,然后进入File Browser的/sparkJobHistory/路径下,点击Upload按钮,上传spark history到该路径下即可。

(四)Spark WebUI进行分析

1.搜索applicationID

进入Spark WebUI页面,在搜索框输入applicationID,即可筛选出该applicationID的spark history。

2.进行stage可视化分析

点击该App ID进去即可看到该applicationID的每一个Job详细运行情况;点击进一个Job,即可看到该Job的DAG图,以及对应的stage运行情况;点击进一个stage,即可看到该stage下所有的task运行情况。通过每一个页面上的运行耗时、GC时间、input/output数据量大小等,根据这些信息即可分析出异常的task、stage、job。

(五)查看相关代码段

1.定位异常Job

通过applicationID进入到我们要分析的Job的运行情况页面后,可以看到该App ID下每一个Job,一般通过观察每一个Job的运行时长可以识别出哪一个Job是异常的,通常运行时间过长的Job就是异常的,可以进入该Job的详细页面进行进一步分析。

2.回溯Job对应代码段

一般定位到异常的Job我们就可以知道对应的代码段,通常这个Job运行情况页会显示其对应的代码行,通过回到代码中找到这个代码行,其前后一小部分代码段就是这个异常Job的执行代码段。

(六)分析与定位问题

1.列出代码段涉及的源表

如果是SparkSQL代码,可以通过SQL直观获取到其所涉及的源表,将这些源表记录下来,以便后续分析。

如果是SparkRDD代码,可以通过代码中所使用的数据集追溯到该数据集所对应的源表,同样,我们把它们记录下来,以便后续进行分析。

2.分析源表的使用方式:广播、普通关联、…

我们可以通过代码中分析出这些源表的使用方式。最常见的应该是对小表进行广播的方式。所谓广播,就是把小表的数据完整地发送到集群的各个DataNode本地缓存起来,当大表与之进行关联操作时,存在于各个DataNode之上的大表数据块便可以根据就近计算原则,与小表数据进行关联计算,从而减少了网络传输,提高了运行速度。

在SparkSQL中,一般如果大表和小表进行关联,会通过hint语法对小表进行广播,具体来说是使用/*mapjoin(small_table_name)*/这样的形式。

而在SparkRDD中,一般也会对小表进行广播操作,通过broadcast()接口进行实现。在Java中,具体来说是使用Broadcast data_broadcast = JavaSparkContext.broadcast(table_data.collect());这样的语法进行实现。

对于普通关联,即没有对表进行特殊处理的关联。这种写法一般在大小表关联的场景下容易出现性能问题,需要特别关注。经常可以作为问题分析的切入点。

3.查看源表数据量

一般通过第一步把问题代码段中所涉及的源表罗列出来后,就需要到生产查看这些源表的数据量是多少,以方便分析是否是因为数据量过大而导致的性能问题,一般如果是数据量导致的问题,多半是因为资源不足,可以考虑通过调整资源数量来解决。

当然,除了常规的查看源表的记录数外,还可以查看该表在HDFS上占用的空间大小。

查看源表记录数SQL:

select count(1) as cnt from db_name.table_name where pt_dt=’xxxx-xx-xx’;

查看源表占用的空间大小,这里使用GB为单位(102410241024)显示:

hadoop fs -du /user/hive/warehouse/db_name.db/ table_name/pt_dt='xxxx-xx-xx' | awk ‘${SUM+=$1} END {print SUM/(1024*1024*1024)}'

4.查看源表数据块分布情况

有时候源表的数据量并不算大,但是还是出现了性能瓶颈,这时候通过观察tasks数的多少,大致可以猜测到是因为源表的数据块大小分布不均匀,或是数据块过少导致的。可以通过以下命令查看源表的数据块分布情况:

hadoop fs -ls -h /user/hive/warehouse/db_name.db/ table_name/pt_dt='xxxx-xx-xx'

通过该命令的输出我们可以看到源表的每一个数据块大小,以此有多少个数据块。举个例子,如果数据块只有2~3块,第一个数据块有80MB,第二、第三个数据块分别只有1KB,那基本可以判定这几个数据块分布不合理。

数据块分布不合理可以通过对源表数据进行重分布(repartition)或设置spark处理的每个map数据块大小上限来前置将过大的数据块分散到各个task中处理,以减少关键task的处理耗时,提升程序性能。

三、总结

本文深入浅出,具体到步骤和实际操作,带领大家从获取作业applicationID,到下载Spark history,再到上传Spark history至开发环境,再进行Spark WebUI分析异常stage,再而定位到问题代码段,最后给出一般问题的分析方向以及分析方法。

对于Spark相关问题的分析,最直接有效的就是对Spark history的分析了,希望大家能通过练习和实操掌握这项技能。当然,平时进行Spark、Hadoop生态体系的理论知识积累也是必不可少的,所谓万丈高楼平地起,根基要稳,才能让楼起得更高。

从0到1进行Spark history分析的更多相关文章

  1. Apache Spark 2.2.0 中文文档 - Spark RDD(Resilient Distributed Datasets)论文 | ApacheCN

    Spark RDD(Resilient Distributed Datasets)论文 概要 1: 介绍 2: Resilient Distributed Datasets(RDDs) 2.1 RDD ...

  2. Spark集群之Spark history server额外配置

     Note: driver在SparkContext使用stop()方法后才将完整的信息提交到指定的目录,如果不使用stop()方法,即使在指定目录中产生该应用程序的目录,history server ...

  3. Spark源代码分析之六:Task调度(二)

    话说在<Spark源代码分析之五:Task调度(一)>一文中,我们对Task调度分析到了DriverEndpoint的makeOffers()方法.这种方法针对接收到的ReviveOffe ...

  4. 【转】Spark History Server 架构原理介绍

    [From]https://blog.csdn.net/u013332124/article/details/88350345 Spark History Server 是spark内置的一个http ...

  5. Apache Spark 2.2.0 中文文档 - Spark RDD(Resilient Distributed Datasets)

    Spark RDD(Resilient Distributed Datasets)论文 概要 1: 介绍 2: Resilient Distributed Datasets(RDDs) 2.1 RDD ...

  6. Android 9.0 默认输入法的设置流程分析

    Android 输入法设置文章 Android 9.0 默认输入法的设置流程分析 Android 9.0 添加预置第三方输入法/设置默认输入法(软键盘) 前言 在上一篇文章  Android 9.0 ...

  7. Spark History Server配置使用

    Spark history Server产生背景 以standalone运行模式为例,在运行Spark Application的时候,Spark会提供一个WEBUI列出应用程序的运行时信息:但该WEB ...

  8. Spark学习笔记-使用Spark History Server

    在运行Spark应用程序的时候,driver会提供一个webUI给出应用程序的运行信息,但是该webUI随着应用程序的完成而关闭端口,也就是 说,Spark应用程序运行完后,将无法查看应用程序的历史记 ...

  9. Apache Spark 2.2.0 中文文档 - Spark SQL, DataFrames and Datasets Guide | ApacheCN

    Spark SQL, DataFrames and Datasets Guide Overview SQL Datasets and DataFrames 开始入门 起始点: SparkSession ...

随机推荐

  1. [PyTorch 学习笔记] 5.1 TensorBoard 介绍

    本章代码: https://github.com/zhangxiann/PyTorch_Practice/blob/master/lesson5/tensorboard_methods.py http ...

  2. 基于Celery在多台云服务器上实现分布式

    起源 最近参加公司里的一个比赛,比赛内容里有一项是尽量使用分布式实现项目.因为项目最终会跑在jetsonnano,一个贼卡的开发板,性能及其垃圾.而且要求使用python? 找了很多博客,讲的真的是模 ...

  3. POJ-2104-K-th Number(区间第K大+主席树模板题)

    Description You are working for Macrohard company in data structures department. After failing your ...

  4. MySQL查询point类型类型的坐标,返回经度纬度

    location字段为point类型的空间坐标 SELECT id, name, address, x(location) as 经度, Y(location) as 纬度, ROUND( 6378. ...

  5. git多账号使用

    1 背 景 在公司上班的员工会同时拥有两个git账号, 一个是公司内部的, 仅允许工作时使用; 另一个是个人的, 常用于日常的学习记录. 此时, 面临的问题是如何在一台电脑(客户端)上正常使用两个账号 ...

  6. Httprunner框架学习

    前言 HttpRunner 是一款面向 HTTP(S) 协议的通用测试框架,只需编写维护一份 YAML/JSON 脚本,即可实现自动化测试. 官方文档:https://docs.httprunner. ...

  7. Linked List 单向链表

    Linked List 链表的理解 小结 链表是以节点的方式来储存的 每个节点包括 data域:存放数据,next域:指向下一个节点 如图:发现链表的各个节点不一定是连续储存的 链表分为带头节点的链表 ...

  8. 解Bug之路-串包Bug

    解Bug之路-串包Bug 笔者很热衷于解决Bug,同时比较擅长(网络/协议)部分,所以经常被唤去解决一些网络IO方面的Bug.现在就挑一个案例出来,写出分析思路,以飨读者,希望读者在以后的工作中能够少 ...

  9. oracle之SQL的基本函数

    SQL的基本函数 2.1 单行函数与多行函数 单行函数:指一行数据输入,返回一个值的函数.所以查询一个表时,对选择的每一行数据都返回一个结果. SQL>select empno,lower(en ...

  10. [程序员代码面试指南]最长递增子序列(二分,DP)

    题目 例:arr=[2,1,5,3,6,4,8,9,7] ,最长递增子序列为1,3,4,8,9 题解 step1:找最长连续子序列长度 dp[]存以arr[i]结尾的情况下,arr[0..i]中的最长 ...