转载标明出处 http://www.cnblogs.com/haozhengfei/p/07ef4bda071b1519f404f26503fcba44.html


Spark_总结七_troubleshooting

1.yarn-client模式引起网卡流量激增问题?

一个Driver和Executor中的task频繁进行通信,通信消息特别多,通信的频率特别高,运行完一个stage,接着运行下一个stage,又是频繁的通信。

   解决:yarn-cluster
 
    yarn-client模式,通常咱们就只会使用在测试环境中,你写好了某个spark作业,打了一个jar包,在某台测试机器上,用yarn-client模式去提交一下。因为测试的行为是偶尔为之的,不会长时间连续提交大量的spark作业去测试。还有一点好处,yarn-client模式提交,可以在本地机器观察到详细全面的log通过查看log,可以去解决线上报错的故障(troubleshooting)、对性能进行观察并进行性能调优。
    实际上线了以后,在生产环境中,都得用yarn-cluster模式,去提交你的spark作业。
yarn-cluster模式,就跟你的本地机器引起的网卡流量激增的问题,就没有关系了。也就是说,
就算有问题,也应该是yarn运维团队和基础运维团队之间的事情了。他们去考虑Yarn集群里面每台机器是虚拟机还是物理机呢?网卡流量激增后会不会对其他东西产生影响呢?如果网络流量激增,要不要给Yarn集群增加一些网络带宽等等这些东西。那就是他们俩个团队的事情了,和你就没有关系了
 
   大公司都是通过Yarn来进行调度,mapreduce on yarn、spark on yarn、甚至storm on yarn

2.yarn-cluster 会报JVM栈内存溢出问题?

问题描述一:
    yarn-client   PermGen 128M
    yarn-cluster PermGen  82M
   有的时候,运行一些包含了spark sql的spark作业,可能会碰到yarn-client模式下,可以正常提交运行;
yarn-cluster模式下,可能是无法提交运行的,会报出JVM的PermGen(永久代)的内存溢出,OOM。
PermGen(永久代)-->JVM里面的一个区域,就是会放Class里面一些字符串常量这些东西的。
 
   yarn-client模式下,driver是运行在本地机器上的,spark使用的JVM的PermGen的配置,
是本地的spark-class文件(spark客户端是默认有配置的),JVM的永久代的大小是128M,
这个是没有问题的;但是呢,在yarn-cluster模式下,driver是运行在yarn集群的某个节点上的,
使用的是没有经过配置的默认设置(PermGen永久代大小),82M。
 
   spark-sql,它的内部是要进行很复杂的SQL的语义解析、语法树的转换等等,特别复杂,
在这种复杂的情况下,如果说你的sql本身特别复杂的话,很可能会比较导致性能的消耗,内存的消耗。
可能对PermGen永久代的占用会比较大。
 
   所以,此时,如果对永久代的占用需求,超过了82M的话,但是呢又在128M以内;就会出现如上所述的问题,
yarn-client模式下,默认是128M,这个还能运行;如果在yarn-cluster模式下,默认是82M,就有问题了。
会报出PermGen Out of Memory error log。
 
问题解决:
        spark-submit提交任务的脚本中,加入以下配置即可:
        --conf spark.driver.extraJavaOptions="-XX:PermSize=128M -XX:MaxPermSize=256M"
 
问题描述二:
   spark sql,sql,要注意,一个问题
                                 JVM Stack Memory Overflow,栈内存溢出
   sql,有大量的or语句。比如where keywords='' or keywords='' or keywords=''当达到or语句,有成百上千的时候,此时可能就会出现一个driver端的jvm stack overflow,JVM栈内存溢出的问题
   JVM栈内存溢出,基本上就是由于调用的方法层级过多,因为产生了大量的,非常深的,超出了JVM栈深度限制的,递归。递归方法。我们的猜测,spark sql,有大量or语句的时候,spark sql内部源码中,在解析sql,比如转换成语法树,或者进行执行计划的生成的时候,对or的处理是递归。or特别多的话,就会发生大量的递归。
 
问题解决:
   这种时候,建议不要搞那么复杂的spark sql语句。采用替代方案:将一条sql语句,拆解成多条sql语句来执行。每条sql语句,就只有100个or子句以内;一条一条SQL语句来执行。根据生产环境经验的测试,一条sql语句,100个or子句以内,是还可以的。通常情况下,不会报那个栈内存溢出。
 

3.序列化导致的报错?

问题描述:
    用client模式去提交spark作业,观察本地打印出来的log。如果出现了类似于Serializable、Serialize等等字眼,报错的log,那么恭喜大家,就碰到了序列化问题导致的报错。
 
问题解决:
 
   1、你的算子函数里面,如果使用到了外部的自定义类型的变量(executor中使用到了外部变量),那么此时,就要求你的自定义类型,必须是可序列化的。
 
   2、如果要将自定义的类型,作为RDD的元素类型,那么自定义的类型也必须是可以序列化的
  1. JavaPairRDD<Integer,Teacher> teacherRDD
  2. JavaPairRDD<Integer,Student> studentRDD
  3. studentRDD.join(teacherRDD)
  4. publicclassTeacherimplementsSerializable{
  5. }
  6. publicclassStudentimplementsSerializable{
  7. }
序列化:
1、executor中使用到了Driver端的变量(自定义对象)
2、RDD<Person> Person
3、RDD持久化的时候    _SER

4.解决算子函数返回NULL导致问题

问题描述:
    在算子函数中,返回null,有些算子函数里面,是需要我们有一个返回值的。但是,有时候,我们可能对某些值,就是不想有什么返回值。如果直接返回NULL的话,会报错的!!!
  1. return actionRDD.mapToPair(newPairFunction<Row,String,Row>(){
  2. privatestaticfinallong serialVersionUID =1L;
  3. @Override
  4. publicTuple2<String,Row> call(Row row)throwsException{
  5. returnnewTuple2<String,Row>("-666",RowFactory.createRow("-999"));
  6. returnnull
  7. }
  8. });
问题解决:
   1、在返回的时候,返回一些特殊的值,不要返回null,比如“-999”
   2、在通过算子获取到了一个RDD之后,可以对这个RDD执行filter操作,进行数据过滤。

filter内,可以对数据进行判定,如果是-999,那么就返回false,给过滤掉就可以了。
   3、大家不要忘了,之前咱们讲过的那个算子调优里面的coalesce算子,在filter之后,

可以使用coalesce算子压缩一下RDD的partition的数量,让各个partition的数据比较紧凑一些。
也能提升一些性能。

5.YARN队列资源不足导致的Application直接失败

问题描述:
   yarn 队列?队列资源:mem core
   如果说,你是基于yarn来提交spark。比如yarn-cluster或者yarn-client。你可以指定提交到哪个yarn队列上的,每个队列都是可以有自己的资源的。
   跟大家说一个生产环境中的,给spark用的yarn资源队列的情况:500G内存,200个cpu core。比如说,某个spark application,在spark-submit里面你自己配了,executor,80个;每个executor,4G内存;每个executor,2个cpu core。你的spark作业每次运行,大概要消耗掉320G内存,以及160个cpu core。乍看起来,咱们的队列资源,是足够的,500G内存,200个cpu core。
   首先,第一点,你的spark作业实际运行起来以后,耗费掉的资源量,可能是比你在spark-submit里面配置的,以及你预期的,是要大一些的。400G内存,190个cpu core。那么这个时候,的确,咱们的队列资源还是有一些剩余的。但是问题是,如果你同时又提交了一个spark作业上去,一模一样的。那就可能会出问题。第二个spark作业,又要申请320G内存+160个cpu core。结果,发现队列资源不足。。。。
   此时,可能会出现两种情况:(备注,具体出现哪种情况,跟你的YARN、Hadoop的版本,你们公司的一些运维参数,以及配置、硬件、资源肯能都有关系)
   1、YARN,发现资源不足时,你的spark作业,并没有等待在那里,等待资源的分配,而是直接打印一行fail的log,直接就fail掉了。
   2、YARN,发现资源不足,你的spark作业,就等待在那里。一直等待之前的spark作业执行完,等待有资源分配给自己来执行。
 
问题解决:
   1、在你的J2EE(我们这个项目里面,spark作业的运行,之前说过了,J2EE平台触发的,执行spark-submit脚本),限制,同时只能提交一个spark作业到yarn上去执行,确保一个spark作业的资源肯定是有的。
   2、你应该采用一些简单的调度区分的方式,比如说,你有的spark作业可能是要长时间运行的,
比如运行30分钟;有的spark作业,可能是短时间运行的,可能就运行2分钟。此时,都提交到一个队列上去,肯定不合适。很可能出现30分钟的作业卡住后面一大堆2分钟的作业。分队列,可以申请(跟你们的YARN、Hadoop运维的同学申请)。你自己给自己搞两个调度队列。每个队列的根据你要执行的作业的情况来设置。在你的J2EE程序里面,要判断,如果是长时间运行的作业,就干脆都提交到某一个固定的队列里面去;如果是短时间运行的作业,就统一提交到另外一个队列里面去。这样,避免了长时间运行的作业,阻塞了短时间运行的作业。   
   3、你的队列里面,无论何时,只会有一个作业在里面运行。那么此时,就应该用我们之前讲过的性能调优的手段,去将每个队列能承载的最大的资源,分配给你的每一个spark作业,比如80个executor;6G的内存;3个cpu core。尽量让你的spark作业每一次运行,都达到最满的资源使用率,最快的速度,最好的性能;并行度,240个cpu core,720个task。
   4、在J2EE中,通过线程池的方式(一个线程池对应一个资源队列),来实现上述我们说的方案。在J2EE平台里面,怎么控制你的资源队列同时只能跑一个作业???可以用线程池来控制,创建线程池容量只有1的这么一个线程池,每一次提交一个作业,就会到这个线程池里面去,它空闲的时候就会有一个作业去跑,后面如果再有一个作业要跑的话,也扔到这个线程池里面,当然它的容量只有1,后面的这些作业线程要去执行,要去启动spark作业的线程,它就会在那里排队,这个线程池自动的给你实现了这个排队机制,不同的作业要放到不同的资源队列里面去运行,那就很简单嘛!不同的作业放到不同的线程池!你可以搞多个线程池,每个线程池就对应着一个资源队列!
  1. ExecutorService threadPool =Executors.newFixedThreadPool(1);
  2. threadPool.submit(newRunnable(){
  3. @Override
  4. publicvoid run(){
  5. }
  6. });
 
   spark如何提交到指定的资源队列中
 

补充:

1.yarn-client执行流程_Driver在整个Spark集群中的作用?

   1,在客户端给我们启动一个Driver
   2,去ResourceManager申请启动container
   3,通知一个NodeManager在container里面启动ApplicationMaster
   4,ApplicationMaster去找ResourceManager申请Executor
   5,ResourceManager返回可以启动的NodeManager的地址
   6,ApplicationMaster去找NodeManager启动Executor
   7,Executor进程会反过来去向Driver注册上去
   8,最后Driver接收到了Executor资源之后就可以去进行我们spark代码的执行了
   9,执行到某个action就触发一个Job
   10,DAGScheduler会划分JOB为一个个Stage
   11,TaskScheduler会划分Stage为一个个Task
   12,Task发送到Executor执行
   13,Driver就来进行Task的调度,并接受Executor中task执行的结果

2.yarn-cluster执行流程

    1.在客户端提交我们执行任务的命令,这时客户端发送请求到ResourceManager,请求启动ApplicationMaster
    2.ResourceManager收到请求后,在某个NodeManager中分配Container,并启动ApplicationMaster(这个ApplicationMaster相当于Driver)
    3.ApplicationMaster发送请求到ResourceManager,请求一批Container,用于启动Executor
    4.Application得到ResourceManager的响应后,在NodeManager启动Executor,这里的NodeManager相当于Spark standalone模式下的Worker节点
    5.当Executor启动之后,会反向注册到Driver(ApplicationMaster)中
    6.接下来开始执行我们的代码,执行到某个action就触发一个Job
 
   1,spark-submit脚本提交spark application到ResourceManager
   2,去ResourceManager申请启动ApplicationMaster
   3,通知一个NodeManager去启动ApplicationMaster(Driver进程)
   4,ApplicationMaster去找ResourceManager申请Executor
   5,ResourceManager分配container,container代表你能启动的Executor占有的资源,包括内存+CPU

返回已经启
   
   
   
 
container的NodeManager的地址
   6,ApplicationMaster去找NodeManager在container里面申请启动Executor
   7,Executor进程会反过来去向Driver注册上去
   8,最后Driver接收到了Executor资源之后就可以去进行我们spark代码的执行了
   9,执行到某个action就触发一个JOB
   10,DAGScheduler会划分JOB为一个个Stage
   11,TaskScheduler会划分Stage为一个个Task
   12,Task发送到Executor执行
   13,Driver就来进行Task的调度
 
   到这里为止,ApplicationMaster(Driver),就知道自己有哪些资源可以用(executor)。
然后就会去执行job、拆分stage、提交stage的task,进行task调度,分配到各个executor上面去执行。

3.ApplicationMaster

   yarn中的核心概念,任何要在yarn上启动的作业类型(mr、spark),都必须有一个。

每种计算框架(mr、spark),如果想要在yarn上执行自己的计算应用,那么就必须自己实现和
提供一个ApplicationMaster

相当于是实现了yarn提供的接口(spark自己开发的一个类)
   
spark
   
   
yarn-client模式下,application的注册(executor的申请)和计算task的调度,是分离开来的。
      standalone模式下,这两个操作都是Driver负责的。
   ApplicationMaster(ExecutorLauncher)负责executor的申请;Driver负责job和stage的划分,
以及task的创建、分配和调度

4.Yarn集群分成两种节点:

   ResourceManager    负责资源的调度
   NodeManager   负责资源的分配、应用程序执行这些东西

5.Driver到底是什么?

   我们写的spark程序,打成jar包,用spark-submit来提交。jar包中的一个main类,通过jvm的命令启动起来。
JVM进程,这个进程,其实就是咱们的Driver进程。Driver进程启动起来以后,执行我们自己写的main函数,从new SparkContext()。。。

6.总结一下yarn-client和yarn-cluster模式的不同之处:

   yarn-client模式,driver运行在本地机器上的;
   yarn-cluster模式,driver是运行在yarn集群上某个nodemanager节点上面的。
 
   yarn-client会导致本地机器负责spark作业的调度,所以网卡流量会激增;
   yarn-cluster模式就没有这个问题。
 
   yarn-client的driver运行在本地,通常来说本地机器跟yarn集群都不会在一个机房的,性能可能不是特别好;
   yarn-cluster模式下,driver是跟yarn集群运行在一个机房内,性能上来说,也会好一些。
 
©All rights reserved

Spark_总结七_troubleshooting的更多相关文章

  1. 如何一步一步用DDD设计一个电商网站(七)—— 实现售价上下文

    阅读目录 前言 明确业务细节 建模 实现 结语 一.前言 上一篇我们已经确立的购买上下文和销售上下文的交互方式,传送门在此:http://www.cnblogs.com/Zachary-Fan/p/D ...

  2. CRL快速开发框架系列教程七(使用事务)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  3. 《LoadRunner12七天速成宝典》来了

    看到自己的新书又要发行了,算算从09年第一本书开始,不知不觉已经是第四本书了(帮朋友合写的书不算),每次写完之后都会说太累了,不想再写了,但是却又次次反悔,吞下食言的苦果.如果非要说第四本书的感受,那 ...

  4. 【SAP业务模式】之ICS(七):IDOC配置

    这是ICS业务模式系列的最后一篇了,主要讲解IDOC的配置. 一.指定EDI传输的供应商逻辑地址 事务代码:WEL1 注意:上面逻辑地址是生产公司+内部客户.有以下两种情形: 1.如果内部客户都是纯数 ...

  5. 我的MYSQL学习心得(七) 查询

    我的MYSQL学习心得(七) 查询 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

  6. Nodejs之MEAN栈开发(七)---- 用Angular创建单页应用(下)

    上一节我们走通了基本的SPA基础结构,这一节会更彻底的将后端的视图.路由.控制器全部移到前端.篇幅比较长,主要分页面改造.使用AngularUI两大部分以及一些优化路由.使用Angular的其他指令的 ...

  7. Go语言实战 - 网站性能优化第一弹“七牛云存储”

    由于用户纷纷反应山坡网的打开速度比较慢,所以两天前我们决定把服务器从linode迁移到阿里云. 整个迁移过程非常平滑,基本上一个小时就完成了.而且阿里云的配套设施提供的也很不错,运行状态监控什么的都有 ...

  8. redis成长之路——(七)

    扩展性封装 虽说现在StackExchange.Redis免费,万一到时候和servicestack.redis一样要收费呢,所以先留一口,后续的可以再处理 实例代码点击这里查看 redis成长之路- ...

  9. discuz接入七牛sdk

    自己摸索了几天,找群里面的人各种问,都没有一个人回答我,哎,国内的开源精神呢...... 需要修改有以下几个: 1.替换 /source/class/class_core.php 文件   解释:就 ...

随机推荐

  1. webpack3.x基本配置与总结

    基本配置 1.开始之前,请确定你已经安装了当前 Node 的较新版本. 2.然后在文件夹根目录下执行以下命令初始化项目并全局安装webpack: 1.$ cnpm init // 初始化项目 2.$ ...

  2. 有关opacity或RGBA设置颜色值及元素的透明值

    opacity声明来设置元素的透明值,当opacity设置元素的透明值,内部的文字及元素也会透明,通过RGBA设置的颜色值只针对当前元素,内部的文字及元素的透明值并未发生变化   opacity声明来 ...

  3. CSS图片翻转动画技术详解

    因为不断有人问我,现在我补充一下:IE是支持这种技术的!尽管会很麻烦.需要做的是旋转front和back元素,而不是旋转整个容器元素.如果你使用的是最新版的IE,可以忽略这一节.IE10+是支持的,I ...

  4. 前端之 HTML🎃

    HTML这知识点很多很杂,所以整理很乱.所以将就看.

  5. vue2 vue-router 组装

    适用于vue cli搭建的项目 vue-router模块下载及记录到package.json中: npm i vue-router -D main.js中: import VueRouter from ...

  6. angular4.0如何引入外部插件1:import方案

    引入外部插件是项目中非常重要的环节.因为部分插件以js语法写的,而ng4用的是ts语法,所以在引入时需要配置. Step1:引入swiper插件的js文件[css在下面会讲到,先别急] 很重要的意见: ...

  7. js 客户端打印html 并且去掉页眉、页脚

    print() 方法用于打印当前窗口的内容,支持部分或者整个网页打印. 调用 print() 方法所引发的行为就像用户单击浏览器的打印按钮.通常,这会产生一个对话框,让用户可以取消或定制打印请求. w ...

  8. 安卓电量优化之WakeLock锁机制全面解析

    版权声明:本文出自汪磊的博客,转载请务必注明出处. 一.WakeLock概述 wakelock是一种锁的机制,只要有应用拿着这个锁,CPU就无法进入休眠状态,一直处于工作状态.比如,手机屏幕在屏幕关闭 ...

  9. sublime自动保存(失去焦点自动保存)

    sublime是轻量的编辑器,经常用sublime编辑器来做一些小例子,使用起来很方便. 在使用sublime的时候需要不断的 ctrl + s 保存代码,才能看到效果. 这样的操作很繁琐,保存的多了 ...

  10. [Spark性能调优] 源码补充 : Spark 2.1.X 中 Unified 和 Static MemoryManager

    本课主题 Static MemoryManager 的源码鉴赏 Unified MemoryManager 的源码鉴赏 引言 从源码的角度了解 Spark 内存管理是怎么设计的,从而知道应该配置那个参 ...