Apache Spark 2.0 在作业完成时却花费很长时间结束

现象

大家在使用 Apache Spark 2.x 的时候可能会遇到这种现象:虽然我们的 Spark Jobs 已经全部完成了,但是我们的程序却还在执行。比如我们使用 Spark SQL 去执行一些 SQL,这个 SQL 在最后生成了大量的文件。然后我们可以看到,这个 SQL 所有的 Spark Jobs 其实已经运行完成了,但是这个查询语句还在运行。通过日志,我们可以看到 driver 节点正在一个一个地将 tasks 生成的文件移动到最终表的目录下面,当我们作业生成的文件很多的情况下,就很容易产生这种现象。本文将给大家介绍一种方法来解决这个问题。

为什么会造成这个现象

Spark 2.x 用到了 Hadoop 2.x,其将生成的文件保存到 HDFS 的时候,最后会调用了 saveAsHadoopFile,而这个函数在里面用到了 FileOutputCommitter,如下:

问题就出在了 Hadoop 2.x 的 FileOutputCommitter 实现FileOutputCommitter 里面有两个值得注意的方法:commitTask 和 commitJob。在 Hadoop 2.x 的FileOutputCommitter 实现里面,mapreduce.fileoutputcommitter.algorithm.version 参数控制着 commitTask 和 commitJob 的工作方式。具体代码如下(为了说明方便,我去掉了无关紧要的语句,完整代码可以参见 FileOutputCommitter.java):

大家可以看到 commitTask 方法里面,有个条件判断 algorithmVersion == 1,这个就是 mapreduce.fileoutputcommitter.algorithm.version 参数的值,默认为1;如果这个参数为1,那么在 Task 完成的时候,是将 Task 临时生成的数据移到 task 的对应目录下,然后再在 commitJob 的时候移到最终作业输出目录,而这个参数,在 Hadoop 2.x 的默认值就是 1!这也就是为什么我们看到 job 完成了,但是程序还在移动数据,从而导致整个作业尚未完成,而且最后是由 Spark 的 Driver 执行 commitJob 函数的,所以执行的慢也是有到底的。

而我们可以看到,如果我们将 mapreduce.fileoutputcommitter.algorithm.version 参数的值设置为 2,那么在 commitTask 执行的时候,就会调用 mergePaths 方法直接将 Task 生成的数据从 Task 临时目录移动到程序最后生成目录。而在执行 commitJob 的时候,直接就不用移动数据了,自然会比默认的值要快很多。

注意,其实在 Hadoop 2.7.0 之前版本,我们可以将 mapreduce.fileoutputcommitter.algorithm.version 参数设置为非1的值就可以实现这个目的,因为程序里面并没有限制这个值一定为2,。不过到了 Hadoop 2.7.0,mapreduce.fileoutputcommitter.algorithm.version 参数的值必须为1或2,具体参见 MAPREDUCE-4815。

怎么在 Spark 里面设置这个参数

问题已经找到了,我们可以在程序里面解决这个问题。有以下几种方法:

  • 直接在 conf/spark-defaults.conf 里面设置 spark.hadoop.mapreduce.fileoutputcommitter.algorithm.version 2,这个是全局影响的。
  • 直接在 Spark 程序里面设置,spark.conf.set("mapreduce.fileoutputcommitter.algorithm.version", "2"),这个是作业级别的。
  • 如果你是使用 Dataset API 写数据到 HDFS,那么你可以这么设置 dataset.write.option("mapreduce.fileoutputcommitter.algorithm.version", "2")。

不过如果你的 Hadoop 版本为 3.x,mapreduce.fileoutputcommitter.algorithm.version 参数的默认值已经设置为2了,具体参见 MAPREDUCE-6336 和 MAPREDUCE-6406。

因为这个参数对性能有一些影响,所以到了 Spark 2.2.0,这个参数已经记录在 Spark 配置文档里面了 configuration.html,具体参见 SPARK-20107。

总结

以上所述是小编给大家介绍的Apache Spark 2.0 在作业完成时却花费很长时间结束,希望对大家有所帮助!

(0)

相关推荐

  • 详解如何使用Spark和Scala分析Apache访问日志

    安装 首先需要安装好Java和Scala,然后下载Spark安装,确保PATH 和JAVA_HOME 已经设置,然后需要使用Scala的SBT构建Spark如下: $ sbt/sbt assembly 构建时间比较长.构建完成后,通过运行下面命令确证安装成功: $ ./bin/spark-shell scala> val textFile = sc.textFile("README.md") // 创建一个指向 README.md 引用 scala> textFile.co

  • 2018即将推出的Apache Spark 2.4都有哪些新功能

    本文来自于2018年09月19日在 Adobe Systems Inc 举行的Apache Spark Meetup. 即将发布的 Apache Spark 2.4 版本是 2.x 系列的第五个版本. 本文对Apache Spark 2.4 的主要功能和增强功能进行了概述. 新的调度模型(Barrier Scheduling),使用户能够将分布式深度学习训练恰当地嵌入到 Spark 的 stage 中,以简化分布式训练工作流程. 添加了35个高阶函数,用于在 Spark SQL 中操作数组/ma

  • Apache Spark 2.0 在作业完成时却花费很长时间结束

    现象 大家在使用 Apache Spark 2.x 的时候可能会遇到这种现象:虽然我们的 Spark Jobs 已经全部完成了,但是我们的程序却还在执行.比如我们使用 Spark SQL 去执行一些 SQL,这个 SQL 在最后生成了大量的文件.然后我们可以看到,这个 SQL 所有的 Spark Jobs 其实已经运行完成了,但是这个查询语句还在运行.通过日志,我们可以看到 driver 节点正在一个一个地将 tasks 生成的文件移动到最终表的目录下面,当我们作业生成的文件很多的情况下,就很容

  • Vue 实现CLI 3.0 + momentjs + lodash打包时优化

    在vue-cli 2.0时代,webpack的配置是有独立文件的,包含在build目录下,修改也比较方便 到vue-cli 3.0后,webpack配置被整合到vue-cli的配置中了,需要配置一些打包插件比较麻烦了,比如优化momentjs压缩包,使用webpack-bundle-analyzer等- 研究后发现vue-cli 3.0使用了chainWebpack来支持额外的插件配置,其实和2.0是差不多的 我们这里使用momentjs,lodash和webpack-bundle-analyz

  • PHP使用Apache的伪静态功能实现“网页404时跳转指定页面

    需求: 1.例如我之前的网站域名是"www.jb51.net",有一个文章的链接是"www.jb51.net/article-5-1.html" 2.因为业务调整或其他原因,更改了域名和网站结构,域名变更为"www.jb51xxxx.net",那么别人访问"www.jb51.net/article-5-1.html"这个文章链接时就访问不到了.出现如下404情况: 解决方案:  1.在网站根目录下新建一个.htaccess伪静

  • Apache Maven3.6.0的下载安装和环境配置(图文教程)

    目录 apache-maven-3.6.0 下载地址 方法/步骤一 安装 方法/步骤二 环境变量配置 变量 环境 apache-maven-3.6.0 下载地址 不限速下载 或者进入官网按下图下载 方法/步骤一 安装 打开压缩包,将maven压缩包解压至软件安装处,建议D根目录或其他,记住安装位置 类似于 方法/步骤二 环境变量配置 变量 1.新建变量M2_HOME,变量值为maven目录 2.在变量名为Path下新建变量值为maven bin目录 一项 3.通过命令mvn -v验证环境是否配置

  • Pandas Matplotlib保存图形时坐标轴标签太长导致显示不全问题的解决

    目录 前言 1. 问题描述 2. 问题原因 4. 解决方法 结束语 前言 本篇博客主要解决在使用pandas绘制图像并保存时,由于标签太长,导致坐标轴上的标签显示不全的问题.刚遇到问题时调整了一下图片大小,然鹅并没有卵用,于是乎就检索了一下问题,发现没有解决pandas的.查询无果后,查看了一下官方文档,顿悟,这不就是matplotlib嘛,换了一个关键字再查询,果然,就是.所以本篇同样适用于解决matplotlib绘制图像时出现的这个问题. # 部分代码 df_sparsity = disti

  • 解决idea中svn提交时performing vcs refresh时间很长的问题

    出现场景:idea软件重装了一次,项目空间是沿用原来的,所有的项目配置也是之前的,导致svn提交异常缓慢. 1.解决方案:重新建立工作区间project 将svnd的项目导出来,并且配置好项目运行环境 再次提交代码到svn就不卡了 2.将设置的值设为300 3.设置一下这里 重启idea,再次提交到svn 亲测有效!!!! 补充知识:idea使用svn(日常使用) 本文记录了svn的日常使用!!!非常详细!!!持续更新- 更新svn的项目到本地(一般是先更新再进行提交) 选择你的svn(服务器)

  • mysql8.0.14.zip安装时自动创建data文件夹失败服务无法启动

    今天重装系统后,在自己电脑上重新安装mysql,下载ZIP文件后解压,按照网上的教程,一步一个坑,还是始终卡在data文件夹自动创建失败上导致服务无法启动,而手动创建的话初始化data文件夹的时候只会创建2个文件.服务依然无法启动-- 最后盯着路径看了N久,想到会不会是路径上的非法字符问题,原解压文件出来后的文件夹名称时mysql-8.0.14-winx64,把文件夹名称改为mysql后成功自动创建了data文件夹,启动服务成功. 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多

  • 详解关于Vue2.0路由开启keep-alive时需要注意的地方

    Vue2.0 做应用必有的需求就是页面数据需要做缓存,不用每次进入页面都要把数据重新请求一遍,每次页面切换都有段等待数据相应时间,这个用户体验可想有多么蛋疼,所以页面缓存是必要的,啥时候需要更新页面数据呢?可以监听状态变化,或者是手动下拉刷新重新请求数据,酱紫,我想用户体验会做的更好. keep-alive的作用以及好处 在做电商有关的项目中,当我们第一次进入列表页需要请求一下数据,当我从列表页进入详情页,详情页不缓存也需要请求下数据,然后返回列表页,这时候我们使用keep-alive来缓存组件

  • 获取焦点时,利用js定时器设定时间执行动作

    进入正题,先说说定时器. 在javascritp中,有两个关于定时器的专用函数,分别为: 1.倒计定时器:timename=setTimeout("function();",delaytime); 2.循环定时器:timename=setInterval("function();",delaytime); 第一个参数"function()"是定时器触发时要执行的动作,可以是一个函数,也可以是几个函数,函数间用":"隔开即可.比

随机推荐