- 一、Spark作业资源的设置情况
- 二、DataFrame/Dataset/RDD的区别及编程
- 三、Spark中的隐式转换的作用:结合Scala来学习
性能调优的王道,就是增加和分配更多的资源,性能和速度上的提升是显而易见的,基本上,在一定范围之内,增加资源与性能的提升是成正比的。写完了一个复杂的Spark作业之后,进行性能调优的时候,首先第一步,就是要调节最优的资源配置,在这个基础之上,如果说你的Spark作业,能够分配的资源达到了你的能力范围的顶端之后,无法再分配更多的资源了,公司资源有限,那么才是考虑去做后面的这些性能调优的点。
1.分配哪些资源:
executor、每个executor的cpu core数量 、每个executor的memory大小、driver memory。
2.在哪里分配这些资源:
在我们在生产环境中,提交spark作业时,用的spark-submit shell脚本,里面调整对应的参数。参数如下:
3.调节到多大,算是资源利用率最大呢:
Spark Standalone,公司集群上,搭建了一套Spark集群,你应该了解每台机器还能够给你使用的资源情况,比如:大概有多少内存,多少cpu core,那么,设置的时候就根据这个实际的情况,去调节每个Spark作业的资源分配。比如说你的每台机器能够给你使用4G内存,2个cpu core;20台机器,如果设置executor数量为20个,那么每个executor就分配4G内存,2个cpu core。
Yarn 资源队列,需要查看你要提交的yarn资源队列目前的资源剩余及使用情况,然后根据剩余可用的资源进行合理分配设置,比如:500G内存,100个cpu core,如果设置executor数量为50个,那么每个executor就平均最大分配10G内存,2个cpu core,你能使用的资源有多大,就尽量去调节到最大的大小。
4.为什么调节了资源以后,性能可以提升:
增加executor数量:如果executor数量比较少,那么,能够并行执行的task数量就比较少,就意味着,我们的Application的并行执行的能力就很弱。比如有3个executor,每个executor有2个cpu core,那么同时能够并行执行的task就是6个。6个执行完以后,再换下一批6个task执行。增加了executor数量以后,那么就意味着,能够并行执行的task数量,也就变多了。比如原先是6个,现在可能可以并行执行10个,甚至20个,100个,那么并行能力就比之前提升了数倍,相应的,性能(执行的速度),也能提升数倍~数十倍。
增加每个executor的内存大小:如果需要对RDD进行cache,那么更多的内存,就可以缓存更多的数据,将更少的数据写入磁盘,甚至不写入磁盘。减少了磁盘IO消耗。对于shuffle操作,在reduce端会需要内存来存放拉取的数据并进行聚合。如果内存不够,就会写入磁盘。如果给executor分配更多内存以后,可能就只需要将很少量的数据写入磁盘,甚至不需要写入磁盘,减少了磁盘IO,提升了性能。对于task的执行,可能会创建很多对象,如果内存比较小,可能会频繁导致JVM堆内存满了,然后频繁GC垃圾回收。内存加大以后,会很少的触发GC,提高了程序的运行速度。
增加每个executor的cpu core:增加每个executor的cpu core,也是增加了task执行的并行度。因为同一时间每个cpu core只能调用执行一个executor进程中的一个task,那么如果原本20个executor,每个才2个cpu core,能够并行执行的task数量,也就是40个task。现在每个executor的cpu core,增加到了5个,那么能够并行执行的task数量,就是100个task。很明显的,执行的速度,提升了2.5倍。
5.调节Spark任务的并行度:
并行度:其实就是指的是,Spark作业中,各个stage的task数量,也就代表了Spark作业的在各个阶段(stage)的并行度。
- task数量,至少设置成与Spark application的总cpu core数量相同(最理想情况,比如总共150个cpu core,分配了150个task,一起运行,差不多同一时间运行完毕)
- 官方是推荐task数量,设置成spark application总cpu core数量的2~3倍,比如150个cpu core,基本要设置task数量为300~500。实际情况,与理想情况不同的,有些task会运行的快一点,比如50s就完了,有些task,可能会慢一点,要1分半才运行完,所以如果你的task数量,刚好设置的跟cpu core数量相同,可能还是会导致资源的浪费,因为,比如150个task,10个先运行完了,剩余140个还在运行,但是这个时候,有10个cpu core就空闲出来了,就导致了浪费。那如果task数量设置成cpu core总数的2~3倍,那么一个task运行完了以后,另一个task马上可以补上来,就尽量让cpu core不要空闲,同时也是尽量提升spark作业运行的效率和速度,提升性能。
- Spark Application的并行度怎么设置呢?Spark的并行度参数为spark.default.parallelism,需要我们在driver端代码中进行设置,SparkConf conf = new SparkConf().set(“spark.default.parallelism”, “500”)
可
1.前言:
Spark每个模块都有一个核心抽象,Spark-core的核心抽象是RDD,Spark SQL等都基于RDD封装了自己的抽象,在Spark SQL中是DataFrame/DataSet。相对来说RDD是更偏底层的抽象,DataFrame/DataSet是在其上做了一层封装,做了优化,使用起来更加方便。从功能上来说,DataFrame/DataSet能做的事情RDD都能做,RDD能做的事情DataFrame/DataSet不一定能做。
从版本的产生上来看:RDD (Spark1.0) —> Dataframe(Spark1.3) —> Dataset(Spark1.6)
如果同样的数据都给到这三个数据结构,他们分别计算之后,都会给出相同的结果。不同是的他们的执行效率和执行方式。
2.什么是DataFrame:
在Spark中,DataFrame是一种以RDD为基础的分布式数据集,类似于传统数据库中的二维表格。
3.RDD和DataFrame的区别:
DataFrame与RDD的主要区别在于,DataFrame带有schema元信息,即DataFrame所表示的二维表数据集的每一列都带有名称和类型。使得Spark SQL得以洞察更多的结构信息,从而对藏于DataFrame背后的数据源以及作用于DataFrame之上的变换进行了针对性的优化,最终达到大幅提升运行时效率的目标。
RDD,由于无从得知所存数据元素的具体内部结构,Spark Core只能在stage层面进行简单、通用的流水线优化。 DataFrame底层是以RDD为基础的分布式数据集,和RDD的主要区别的是:RDD中没有schema信息,而DataFrame中数据每一行都包含schema。DataFrame = RDD[Row] + shcema
DataFrame还引入了off-heap,意味着JVM堆以外的内存, 这些内存直接受操作系统管理(而不是JVM)。Spark能够以二进制的形式序列化数据(不包括结构)到off-heap中,当要操作数据时,就直接操作off-heap内存。由于Spark理解schema,所以知道该如何操作。
off-heap就像地盘, schema就像地图,Spark有地图又有自己地盘了,就可以自己说了算了,不再受JVM的限制,也就不再收GC的困扰了。通过schema和off-heap,DataFrame解决了RDD的缺点,但是却丢了RDD的优点:DataFrame不是类型安全的,API也不是面向对象风格的。
4.什么是DataSet:
Dataset是一个由特定领域的对象组成强类型(typedrel)集合,可以使用函数(DSL)或关系运算(SQL)进行并行的转换操作。 每个Dataset 还有一个称为“DataFrame”的无类型(untypedrel)视图,它是[[Row]]的数据集。
5.RDD和Dataset的区别:
Dataset与RDD类似,但是,它们不使用Java序列化或Kryo,而是使用专用的Encoder编码器来序列化对象以便通过网络进行处理或传输。虽然Encoder编码器和标准序列化都负责将对象转换为字节,但Encoder编码器是动态生成的代码,并使用一种格式,允许Spark执行许多操作,如过滤,排序和散列,而无需将字节反序列化为对象
6.Dataset和DataFrame的区别与联系:
区别:
- Dataset是强类型typedrel的,会在编译的时候进行类型检测;而DataFrame是弱类型untypedrel的,在执行的时候进行类型检测;
- Dataset是通过Encoder进行序列化,支持动态的生成代码,直接在bytes的层面进行排序,过滤等的操作;而DataFrame是采用可选的java的标准序列化或是kyro进行序列化。
联系:
- 在spark2.x,DataFrame和Dataset的api进行了统一
- 在语法角度,DataFrame是Dataset中每一个元素为Row类型的特殊情况
type DataFrame = Dataset[Row] - DataFrame和Dataset实质上都是一个逻辑计划,并且是懒加载的,都包含着scahema信息,只有到数据要读取的时候,才会将逻辑计划进行分析和优化,并最终转化为RDD
- 二者由于api是统一的,所以都可以采用DSL和SQL方式进行开发,都可以通过sparksession对象进行创建或者是通过transform转化操作得到
- 在对DataFrame和Dataset进行操作许多操作都需要这个包进行支持
7.DataSet的创建:
可以参见官方文档:http://spark.apache.org/docs/2.2.1/sql-programming-guide.html#creating-datasets
8.RDD转DataFrame原因及方式:
可以将RDD转成DataFrame之后,借用sparksql和sql以及HQL语句快速方便的使用sql语句统计和查询,比如说分组排名(row_number() over()) 分析函数和窗口函数去实现占比分析。
将RDD转化为DataFrame有两种方式:
方式一:通过反射推断schema 要求:RDD的元素类型必须是case class
方式二、编程指定schema 要求:RDD的元素类型必须是Row 自己编写schema(StructType) 调用SparkSession的createDatafrmame(RDD[Row],schema)
9.DataFrame转RDD原因及方式:
- 解决一些使用sql难以处理的统计分析
- 将数据写入Mysql。a.DataFrame的write.jdbc,仅支持四种模式:append、overwrite、ignore、default;b.使用rdd的话,除了上述以外还支持insert 和 update操作,还支持数据库连接池 (自定 义,第三方:c3p0 hibernate mybatis)方式,批量高效将大量数据写入 Mysql
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/rfx/70408.html