spark ui_Spark UI的见解

spark ui

作为apache-spark-job解剖的后续文章,我将分享您如何使用Spark UI进行作业调整。 我将继续使用先前文章中使用的相同示例,新的spark应用程序将在以下方面完成工作

–阅读纽约市停车票

–通过“板ID”进行汇总并计算违规日期

–保存结果

此代码的DAG看起来像这样

Spark用户界面

这是多阶段的工作,因此需要一些数据混洗,因为此示例混洗写入为564mb,输出为461MB。

让我们看看我们可以做些什么来减少这种情况?

让我们从“ Stage2”开始采取自上而下的方法。 首先想到的是探索压缩。
当前代码

aggValue.map {case (key, value) => Array(key, value._1, value._2.mkString(",")).mkString("\t")}.saveAsTextFile(s"/data/output/${now}")

新密码

aggValue.map {case (key, value) => Array(key, value._1, value._2.mkString(",")).mkString("\t")}.saveAsTextFile(s"/data/output/${now}", classOf[GzipCodec])

新代码仅在写入时启用gzip,让我们看看我们在Spark UI上看到的内容

Spark用户界面

用Gzip保存

只需写入编码器,写入就减少了70%。 现在达到135Mb并加快了工作速度。

让我们先看看还有什么可能,然后再进行更多的内部调整

最终输出如下所示

1RA32   1       05/07/2014
92062KA 2       07/29/2013,07/18/2013
GJJ1410 3       12/07/2016,03/04/2017,04/25/2015
FJZ3486 3       10/21/2013,01/25/2014
FDV7798 7       03/09/2014,01/14/2014,07/25/2014,11/21/2015,12/04/2015,01/16/2015

进攻日期以原始格式存储,因此可以对此应用很少的编码以获得更快的速度。

Java 8添加了LocalDate来简化日期操作,该类带有一些方便的功能,其中之一就是toEpocDay。

此函数将日期转换为1970年的日期,因此这意味着在4个字节(Int)中,我们最多可以存储5K年,与当前格式占用10个字节相比,这似乎节省了很多。

epocDay的代码段

val issueDate = LocalDate.parse(row(aggFieldsOffset.get("issue date").get), ISSUE_DATE_FORMAT)val issueDateValues = mutable.Set[Int]()issueDateValues.add(issueDate.toEpochDay.toInt)result = (fieldOffset.map(fieldInfo => row(fieldInfo._2)).mkString(","), (1, issueDateValues))

更改后的Spark UI。 我还做了另一项更改以使用KryoSerializer

Spark用户界面

这是一个巨大的改进,随机写入从564Mb更改为409MB(提高27%),输出从134Mb更改为124 Mb(提高8%)

现在让我们转到Spark UI上的另一部分,该部分显示了执行者端的日志。

以上运行的GC日志显示以下内容

2018-10-28T17:13:35.332+0800: 130.281: [GC (Allocation Failure) [PSYoungGen: 306176K->20608K(327168K)] 456383K->170815K(992768K), 0.0222440 secs] [Times: user=0.09 sys=0.00, real=0.03 secs]
2018-10-28T17:13:35.941+0800: 130.889: [GC (Allocation Failure) [PSYoungGen: 326784K->19408K(327168K)] 476991K->186180K(992768K), 0.0152300 secs] [Times: user=0.09 sys=0.00, real=0.02 secs]
2018-10-28T17:13:36.367+0800: 131.315: [GC (GCLocker Initiated GC) [PSYoungGen: 324560K->18592K(324096K)] 491332K->199904K(989696K), 0.0130390 secs] [Times: user=0.11 sys=0.00, real=0.01 secs]
2018-10-28T17:13:36.771+0800: 131.720: [GC (GCLocker Initiated GC) [PSYoungGen: 323744K->18304K(326656K)] 505058K->215325K(992256K), 0.0152620 secs] [Times: user=0.09 sys=0.00, real=0.02 secs]
2018-10-28T17:13:37.201+0800: 132.149: [GC (Allocation Failure) [PSYoungGen: 323456K->20864K(326656K)] 520481K->233017K(992256K), 0.0199460 secs] [Times: user=0.12 sys=0.00, real=0.02 secs]
2018-10-28T17:13:37.672+0800: 132.620: [GC (Allocation Failure) [PSYoungGen: 326016K->18864K(327168K)] 538169K->245181K(992768K), 0.0237590 secs] [Times: user=0.17 sys=0.00, real=0.03 secs]
2018-10-28T17:13:38.057+0800: 133.005: [GC (GCLocker Initiated GC) [PSYoungGen: 324016K->17728K(327168K)] 550336K->259147K(992768K), 0.0153710 secs] [Times: user=0.09 sys=0.00, real=0.01 secs]
2018-10-28T17:13:38.478+0800: 133.426: [GC (Allocation Failure) [PSYoungGen: 322880K->18656K(326144K)] 564301K->277690K(991744K), 0.0156780 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
2018-10-28T17:13:38.951+0800: 133.899: [GC (Allocation Failure) [PSYoungGen: 323808K->21472K(326656K)] 582842K->294338K(992256K), 0.0157690 secs] [Times: user=0.09 sys=0.00, real=0.02 secs]
2018-10-28T17:13:39.384+0800: 134.332: [GC (Allocation Failure) [PSYoungGen: 326624K->18912K(317440K)] 599490K->305610K(983040K), 0.0126610 secs] [Times: user=0.11 sys=0.00, real=0.02 secs]
2018-10-28T17:13:39.993+0800: 134.941: [GC (Allocation Failure) [PSYoungGen: 313824K->17664K(322048K)] 600522K->320486K(987648K), 0.0111380 secs] [Times: user=0.00 sys=0.00, real=0.02 secs] 

让我们专注于一条线

2018-10-28T17:13:39.993+0800: 134.941: [GC (Allocation Failure) [PSYoungGen: 313824K->17664K(322048K)] 600522K->320486K(987648K) , 0.0111380 secs] [Times: user=0.00 sys=0.00, real=0.02 secs] 

次要GC之前的堆为600MB,之后为320MB,总堆大小为987MB。

执行器分配了2GB内存,并且此Spark应用程序未使用所有内存,我们可以通过发送更多任务或更大任务来给执行器增加更多负载。

我将输入分区从270减少到100

Spark用户界面

带270个输入分区

Spark用户界面

带100个输入分区

100个输入分区看起来更好,可减少约10%以上的数据洗牌。

其他技巧

现在,我将分享一些将大大改变GC的东西!

优化前的代码

private def mergeValues(value1: (Int, mutable.Set[Int]), value2: (Int, mutable.Set[Int])): (Int, mutable.Set[Int]) = {val newCount = value1._1 + value2._1val dates = value1._2dates.foreach(d => value2._2.add(d))(newCount, value2._2)}private def saveData(aggValue: RDD[(String, (Int, mutable.Set[Int]))], now: String) = {aggValue.map { case (key, value) => Array(key, value._1, value._2.mkString(",")).mkString("\t") }.coalesce(100).saveAsTextFile(s"/data/output/${now}", classOf[GzipCodec])}

优化后的代码

private def mergeValues(value1: GroupByValue, value2: GroupByValue): GroupByValue = {if (value2.days.size > value1.days.size) {value2.count = value1.count + value2.countvalue1.days.foreach(d => value2.days.add(d))value2}else {value1.count = value1.count + value2.countvalue2.days.foreach(d => value1.days.add(d))value1}}private def saveData(aggValue: RDD[(String, GroupByValue)], now: String) = {aggValue.mapPartitions(rows => {val buffer = new StringBuffer()rows.map {case (key, value) =>buffer.setLength(0)buffer.append(key).append("\t").append(value.count).append("\t").append(value.days.mkString(","))buffer.toString}}).coalesce(100).saveAsTextFile(s"/data/output/${now}", classOf[GzipCodec])}

新代码正在对集合进行优化合并,它向大集合中添加了小集合,并且还引入了Case类。

另一项优化是保存功能,其中它使用mapPartitions通过使用StringBuffer减少对象分配。

我使用http://gceasy.io获得了一些GC统计信息。

Spark用户界面

更改代码之前

Spark用户界面

更改代码后

新代码为例如产生更少的垃圾。

总GC 126 GB和122 GB(约提高4%)

最大GC时间720ms与520 ms(约好25%)

优化看起来很有希望。

该博客中使用的所有代码都可以在github repo sparkperformance上找到

请继续关注有关此内容的更多信息。

翻译自: https://www.javacodegeeks.com/2018/11/insights-spark-ui.html

spark ui

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/332563.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android布局加载慢,Android布局优化(四)X2C — 提升布局加载速度200%

系列文章前言在Android布局优化(一)从布局加载原理说起中我们说到了布局加载的两大性能瓶颈,通过IO操作将XML加载到内存中并进行解析和通过反射创建View。这里介绍一种避免运行时通过IO操作读取布局文件的“黑科技”—X2C。个人认为这个技术在实际项目中使用可能会需…

api 获取网络使用情况_您的API是什么情况?

api 获取网络使用情况免责声明:在纯REST中,API是不透明的,URL应该是对先前请求的响应中作为链接发送的内容。 但是,我不是在讲纯REST,而是在讲更实用的API,其中涉及REST的一些概念以及通用的API最佳实践。 …

判断字符串是不是application/x-www-form-urlencoded字符串(URL编码格式的字符串)

import java.util.BitSet;/*** 判断一个字符串是不是URL编码字符串的工具类,即判断字符串是不是application/x-www-form-urlencoded字符串** author liaowenxiong* date 2022/1/14 11:32*/public class URLEncodeUtils {private static BitSet bitSet;static {bitSe…

数据查询和业务流分开_传统数仓和大数据数仓的区别是什么?

概念与容器为什么先说这个,其实很简单:因为绝大多数人都把这两个概念混为一谈。然后就会出现各种各样的问题:oracle不是数据库么,怎么又是数据仓库?Hive不是数据仓库么?怎么又是数据库?数据仓库…

android 多语言不起作用,Android本地化语言环境不起作用,所有区域代码都存在问题...

我需要将除瑞士之类的子语言环境添加到我的应用程序中,而不是普通的德语.我找到的德语资源文件夹的语言环境扩展名为de.所以我的文件夹名为“values-de”.这很好.然后我添加了“values-de_CH”并继续收到错误“无效的资源目录名称”.我也试过“values-de_rCH”和“values-de_ch…

aws 性能_AWS上的应用程序自动扩展–选项和对性能的影响

aws 性能至关重要的是扩展软件应用程序,以避免由于网站的客户群或需要处理大型数据集的应用程序等导致的工作负载增加而导致性能瓶颈的情况。云服务提供商通常是访问其他应用程序的最佳方法随需应变的资源,可根据应用程序的负载变化来放大或缩小。 1.什…

java中月日年这种怎么转换成年月日_最“热乎”的Java社招面试经历分享(共40个面试题)...

面试时间:2020年10月12日1、final finally finalize的区别2、synchronized关键字的作用以及在什么时候使用,concurrent包里面其它的锁。3、有遇到过死锁的问题吗?(死锁的原理和解决方法)4、hashmap的实现原理,hashmap和hashtable的…

(案例)使用Cookie保存用户最后一次访问的时间

文章目录需求分析示例代码需求 1.访问一个Servlet,如果获取不到上一次访问的时间,则提示:您好,欢迎访问。 2.如果可以获取上一次访问的时间,则提示:您好,欢迎回来,您上次访问时间为…

aws lambda使用_使用AWS Lambda,S3和AWS CloudFront进行动态内容缓存

aws lambda使用快速提供内容对于任何网站或应用程序具有更好的客户体验都是必不可少的。 如果您将网站或应用程序托管在AWS Cloud中,那么无论从何处访问应用程序,都可以以较低的延迟快速提供内容。 AWS提供了CloudFront服务,用于将内容缓存在…

android+阴影+xml,Android 阴影视图 ShadowViewHelper

软件介绍ShadowViewHelper 是 Android 的阴影布局。xml:android:id"id/activity_main_shadow_view_b"android:layout_width"wrap_content" android:layout_height"wrap_content"android:layout_gravity"center"android:layout_marginT…

docker-compose观察实时日志_基于 Flink SQL CDC 的实时数据同步方案

整理:陈政羽(Flink 社区志愿者) Flink 1.11 引入了 Flink SQL CDC,CDC 能给我们数据和业务间能带来什么变化?本文由 Apache Flink PMC,阿里巴巴技术专家伍翀 (云邪)分享,内容将从传统的数据同步方案,基于 F…

android dialog 字体,android – 为AlertDialog的MultiSelectItems设置自定义字体(字体)

AlertDialog.Builder使用AlertController.AlertParams构建对话框.我检查了AlertDialog.Builder #create()调用AlertController.AlertParams #application()如果设置了项目,则创建ListView并分配适配器(AlertParams#createListView()).我基于createListView源创建了自定义适配器…

困难是成功路上的垫脚石_Java是开发的垫脚石。 学习吧!

困难是成功路上的垫脚石Java是全世界使用最广泛的编程语言之一 。 尽管也有很多其他编程语言,但是没有什么可以比Java更好的了。 Java是用于开发移动应用程序,游戏,Web应用程序,桌面应用程序和许多其他令人兴奋的事物的出色语言之…

python 3.6.5 shell_Linux 安装 Python3.6.5

1. 安装依赖环境 yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel 2. 下载 Python 3.6.5 wget https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tgz 3. 创建安装…

你真的会用Mac中的Finder吗?

参加:https://zhuanlan.zhihu.com/p/144139903

用c语言实现mfc系统,MFC实现学生选课系统

本文实例为大家分享了MFC实现学生选课系统的具体代码,供大家参考,具体内容如下先上效果图:主要功能:输入学号,从数据库中查找学号,若找到相匹配的学号,则显示数据库中姓名、学历、导师&#xff…

spring 构造函数注入_Spring构造函数依赖注入示例

spring 构造函数注入欢迎使用Spring构造函数依赖注入示例指南。 基于构造器的依赖注入是Spring 依赖注入的一种 。 依赖注入的另一种类型是Setter注入和字段注入。 有关Spring依赖注入的更多信息: Spring二传手注射的例子 Spring田间注入 依赖注入–构造函数与现…

python用pip安装numpy mac_Mac下python安装numpy,pandas,matplotlib

numpy是数据分析的库,我的目的是分析股票的数据,Pandas 有两种自己独有的基本数据结构Series (一维)和 DataFrame(二维),它们让数据操作更简单了。它也是 Python 的一个库,所以&…

IntelliJ IDEA for Mac工件包(artifact)中 Web facet resources 的模块名称有误,如何修改?

在工件管理界面中,如果某个工件包中 Web facet resources 的模块名称有误,如下图所示: 你可以在项目根目录下的 .idea/artifacts 目录下找到以工件名称命名的 xml 文件,找到其中含有 facet 属性的 element 标签,更正…