sparkSQL1.1入门之九:sparkSQL之调优

spark是一个快速的内存计算框架;同时是一个并行运算的框架。在计算性能调优的时候,除了要考虑广为人知的木桶原理外,还要考虑平行运算的Amdahl定理。

木桶原理又称短板理论,其核心思想是:一只木桶盛水的多少,并不取决于桶壁上最高的那块木块,而是取决于桶壁上最短的那块。将这个理论应用到系统性能优化上,系统的最终性能取决于系统中性能表现最差的组件。例如,即使系统拥有充足的内存资源和CPU资源,但是如果磁盘I/O性能低下,那么系统的总体性能是取决于当前最慢的磁盘I/O速度,而不是当前最优越的CPU或者内存。在这种情况下,如果需要进一步提升系统性能,优化内存或者CPU资源是毫无用处的。只有提高磁盘I/O性能才能对系统的整体性能进行优化。

Amdahl定理,一个计算机科学界的经验法则,因吉恩·阿姆达尔而得名。它代表了处理器平行运算之后效率提升的能力。并行计算中的加速比是用并行前的执行速度和并行后的执行速度之比来表示的,它表示了在并行化之后的效率提升情况。阿姆达尔定律是固定负载(计算总量不变时)时的量化标准。可用公式:来表示。式中分别表示问题规模的串行分量(问题中不能并行化的那一部分)和并行分量,p表示处理器数量。当时,上式的极限是,其中,。这意味着无论我们如何增大处理器数目,加速比是无法高于这个数的。

SparkSQL作为Spark的一个组件,在调优的时候,也要充分考虑到上面的两个原理,既要考虑如何充分的利用硬件资源,又要考虑如何利用好分布式系统的并行计算。由于测试环境条件有限,本篇不能做出更详尽的实验数据来说明,只能在理论上加以说明。

1:并行性

SparkSQL在集群中运行,将一个查询任务分解成大量的Task分配给集群中的各个节点来运行。通常情况下,Task的数量是大于集群的并行度。比如前面第六章和第七章查询数据时,shuffle的时候使用了缺省的spark.sql.shuffle.partitions,即200个partition,也就是200个Task:

而实验的集群环境却只能并行3个Task,也就是说同时只能有3个Task保持Running:

这时大家就应该明白了,要跑完这200个Task就要跑200/3=67批次。如何减少运行的批次呢?那就要尽量提高查询任务的并行度。查询任务的并行度由两方面决定:集群的处理能力和集群的有效处理能力。

  • 对于Spark Standalone集群来说,集群的处理能力是由conf/spark-env中的SPARK_WORKER_INSTANCES参数、SPARK_WORKER_CORES参数决定的;而SPARK_WORKER_INSTANCES*SPARK_WORKER_CORES不能超过物理机器的实际CPU core;
  • 集群的有效处理能力是指集群中空闲的集群资源,一般是指使用spark-submit或spark-shell时指定的--total-executor-cores,一般情况下,我们不需要指定,这时候,Spark Standalone集群会将所有空闲的core分配给查询,并且在Task轮询运行过程中,Standalone集群会将其他spark应用程序运行完后空闲出来的core也分配给正在运行中的查询。

综上所述,sparkSQL的查询并行度主要和集群的core数量相关,合理配置每个节点的core可以提高集群的并行度,提高查询的效率。

2: 高效的数据格式

高效的数据格式,一方面是加快了数据的读入速度,另一方面可以减少内存的消耗。高效的数据格式包括多个方面:

2.1 数据本地性

分布式计算系统的精粹在于移动计算而非移动数据,但是在实际的计算过程中,总存在着移动数据的情况,除非是在集群的所有节点上都保存数据的副本。移动数据,将数据从一个节点移动到另一个节点进行计算,不但消耗了网络IO,也消耗了磁盘IO,降低了整个计算的效率。为了提高数据的本地性,除了优化算法(也就是修改spark内存,难度有点高),就是合理设置数据的副本。设置数据的副本,这需要通过配置参数并长期观察运行状态才能获取的一个经验值。

下面是spark webUI监控Stage的一个图:

  • PROCESS_LOCAL是指读取缓存在本地节点的数据
  • NODE_LOCAL是指读取本地节点硬盘数据
  • ANY是指读取非本地节点数据
  • 通常读取数据PROCESS_LOCAL>NODE_LOCAL>ANY,尽量使数据以PROCESS_LOCAL或NODE_LOCAL方式读取。其中PROCESS_LOCAL还和cache有关。

2.2 合适的数据类型

对于要查询的数据,定义合适的数据类型也是非常有必要。对于一个tinyint可以使用的数据列,不需要为了方便定义成int类型,一个tinyint的数据占用了1个byte,而int占用了4个byte。也就是说,一旦将这数据进行缓存的话,内存的消耗将增加数倍。在SparkSQL里,定义合适的数据类型可以节省有限的内存资源。

2.3 合适的数据列

对于要查询的数据,在写SQL语句的时候,尽量写出要查询的列名,如Select a,b from tbl,而不是使用Select * from tbl;这样不但可以减少磁盘IO,也减少缓存时消耗的内存。

2.4 更优的数据存储格式

在查询的时候,最终还是要读取存储在文件系统中的文件。采用更优的数据存储格式,将有利于数据的读取速度。查看sparkSQL的stage,可以发现,很多时候,数据读取消耗占有很大的比重。对于sqlContext来说,支持 textFiile、SequenceFile、ParquetFile、jsonFile;对于hiveContext来说,支持AvroFile、ORCFile、Parquet File,以及各种压缩。根据自己的业务需求,测试并选择合适的数据存储格式将有利于提高sparkSQL的查询效率。

3:内存的使用

spark应用程序最纠结的地方就是内存的使用了,也是最能体现“细节是魔鬼”的地方。Spark的内存配置项有不少,其中比较重要的几个是:

  • SPARK_WORKER_MEMORY,在conf/spark-env.sh中配置SPARK_WORKER_MEMORY 和SPARK_WORKER_INSTANCES,可以充分的利用节点的内存资源,SPARK_WORKER_INSTANCES*SPARK_WORKER_MEMORY不要超过节点本身具备的内存容量;
  • executor-memory,在spark-shell或spark-submit提交spark应用程序时申请使用的内存数量;不要超过节点的SPARK_WORKER_MEMORY;
  • spark.storage.memoryFraction spark应用程序在所申请的内存资源中可用于cache的比例
  • spark.shuffle.memoryFraction spark应用程序在所申请的内存资源中可用于shuffle的比例

在实际使用上,对于后两个参数,可以根据常用查询的内存消耗情况做适当的变更。另外,在SparkSQL使用上,有几点建议:

  • 对于频繁使用的表或查询才进行缓存,对于只使用一次的表不需要缓存;
  • 对于join操作,优先缓存较小的表;
  • 要多注意Stage的监控,多思考如何才能更多的Task使用PROCESS_LOCAL;
  • 要多注意Storage的监控,多思考如何才能Fraction cached的比例更多

4:合适的Task

对于SparkSQL,还有一个比较重要的参数,就是shuffle时候的Task数量,通过spark.sql.shuffle.partitions来调节。调节的基础是spark集群的处理能力和要处理的数据量,spark的默认值是200。Task过多,会产生很多的任务启动开销,Task多少,每个Task的处理时间过长,容易straggle。

5:其他的一些建议

优化的方面的内容很多,但大部分都是细节性的内容,下面就简单地提提:

  • 想要获取更好的表达式查询速度,可以将spark.sql.codegen设置为Ture;
  • 对于大数据集的计算结果,不要使用collect() ,collect()就结果返回给driver,很容易撑爆driver的内存;一般直接输出到分布式文件系统中;
  • 对于Worker倾斜,设置spark.speculation=true 将持续不给力的节点去掉;
  • 对于数据倾斜,采用加入部分中间步骤,如聚合后cache,具体情况具体分析;
  • 适当的使用序化方案以及压缩方案;
  • 善于利用集群监控系统,将集群的运行状况维持在一个合理的、平稳的状态;
  • 善于解决重点矛盾,多观察Stage中的Task,查看最耗时的Task,查找原因并改善;

由于时间仓促,本篇在以后的版本再增加一些实例。

时间: 2024-11-09 02:20:42

sparkSQL1.1入门之九:sparkSQL之调优的相关文章

sparkSQL1.1入门之六:sparkSQL之基础应用

sparkSQL1.1对数据的查询分成了2个分支:sqlContext 和 hiveContext. 在sqlContext中,sparkSQL可以使用SQL-92语法对定义的表进行查询,表的源数据可以来自: RDD parquet文件 json文件 在hiveContext中,sparkSQL可以使用HQL语法,对hive数据进行查询,sparkSQL1.1支持hive0.12的HQL语法:如果遇上不支持的语法,用户可以通过更改配置切换到sql语法.笔者猜测,从spark1.1开始,将打开sq

sparkSQL1.1入门之八:sparkSQL之综合应用

Spark之所以万人瞩目,除了内存计算,还有其ALL-IN-ONE的特性,实现了One stack rule them all.下面简单模拟了几个综合应用场景,不仅使用了sparkSQL,还使用了其他Spark组件: 店铺分类,根据销售额对店铺分类 货品调拨,根据货品的销售数量和店铺之间的距离进行货品调拨 前者将使用sparkSQL+MLlib的聚类算法,后者将使用sparkSQL+GraphX算法.本实验采用IntelliJ IDEA调试代码,最后生成doc.jar,然后使用spark-sub

sparkSQL1.1入门之三:sparkSQL组件之解析

上篇在总体上介绍了sparkSQL的运行架构及其基本实现方法(Tree和Rule的配合),也大致介绍了sparkSQL中涉及到的各个概念和组件.本篇将详细地介绍一下关键的一些概念和组件,由于hiveContext继承自sqlContext,关键的概念和组件类似,只不过后者针对hive的特性做了一些修正和重写,所以本篇就只介绍sqlContext的关键的概念和组件. 概念: LogicalPlan 组件: SqlParser Analyzer Optimizer Planner 1:Logical

sparkSQL1.1入门之一:为什么sparkSQL

2014年9月11日,Spark1.1.0忽然之间发布.笔者立即下载.编译.部署了Spark1.1.0.关于Spark1.1的编译和部署,请参看笔者博客Spark1.1.0 源码编译和部署包生成 . Spark1.1.0中变化较大是sparkSQL和MLlib,sparkSQL1.1.0主要的变动有: 增加了JDBC/ODBC Server(ThriftServer),用户可以在应用程序中连接到SparkSQL并使用其中的表和缓存表. 增加了对JSON文件的支持 增加了对parquet文件的本地

Spark入门实战系列--6.SparkSQL(中)--深入了解运行计划及调优

[注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 1.1  运行环境说明 1.1.1 硬软件环境 l  主机操作系统:Windows 64位,双核4线程,主频2.2G,10G内存 l  虚拟软件:VMware® Workstation 9.0.0 build-812388 l  虚拟机操作系统:CentOS6.5 64位,单核 l  虚拟机运行环境: Ø  JDK:1.7.0_55 64位 Ø  Hadoop:2.2.0(需要编译为64位) Ø 

sparkSQL1.1入门之十:总结

回顾一下,在前面几章中,就sparkSQL1.1.0基本概念.运行架构.基本操作和实用工具做了基本介绍. 基本概念: SchemaRDD Rule Tree LogicPlan Parser Analyzer Optimizer SparkPlan 运行架构: sqlContext运行架构 hiveContext运行架构 基本操作 原生RDD的操作 parquet文件的操作 json文件的操作 hive数据的操作 和其他spark组件混合使用 实用工具 hive/console的操作 CLI的配

39套精品Java从入门到架构师|高并发|高性能|高可用|分布式|集群|电商缓存|性能调优|设计项目实战|视频教程

精品Java高级课,架构课,java8新特性,P2P金融项目,程序设计,功能设计,数据库设计,第三方支付,web安全,高并发,高性能,高可用,分布式,集群,电商,缓存,性能调优,设计模式,项目实战,大型分布式电商项目实战视频教程   视频课程包含: 39套Java精品高级课架构课包含:java8新特性,P2P金融项目,程序设计,功能设计,数据库设计,架构设计,web安全,高并发,高性能,高可用,高可扩展,分布式,集群,电商,缓存,性能调优,设计模式,项目实战,工作流,程序调优,负载均衡,Solr

Swift入门(九)——String与Int、Double、Float等数字相互转换

三种转换模式 任何语言里面,Int.float.double等数字类型自成一派,但它们和String类型之间的转换总是不太方便,这里总结一下它们相互转换的方法.总结下来一共有三种转换模式,分别举例说明. 一.String转数字 这里以String类型转Int类型为例.String转其他的数字类型(Float.Double等)大同小异.主要用到的方法是String类型的toInt方法.注意这个方法返回的是Int?,即一个整数可选类型.所以需要解封. var string = "1234"

[WebGL入门]十九,遮挡剔除和深度测试

注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中如果有我的额外说明,我会加上[lufy:],另外,鄙人webgl研究还不够深入,一些专业词语,如果翻译有误,欢迎大家指正. 本次的demo的运行结果 多边形的外侧,内侧和遮挡剔除 上次介绍了索引缓存,以及使用IBO来绘图,使用索引缓存可以循环利用重复的顶点,能够提高绘图效率.这之后的文章,如果没有特殊的原因的话,基本上都会使用索引缓存,通过drawElements来绘图.这次来说一下遮挡剔除和深度测试,这是两个重要