通过知网下载此篇文章。于2018年7月发表在计算机科学。
引言
大数据平台的执行环境由于受到底层硬件、体系结构、操作系统、Spark框架本身以及用户编写的应用程序等多层次的综合影响。
如果不了解Spark底层复杂的执行机制,就找不到性能瓶颈,也就无法优化。
Spark工作原理
(这里只记录自己觉得需要注意的地方)
用户的Driver程序通过Action操作划分Job,有多少个Action操作就有多少个Job。Job通过行动操作划分,Stage通过宽窄依赖划分,Task通过并行度划分。
Pig和Hive都是基于MapReduce的上层封装,已达到简易使用MapReduce的作用。
开发原则优化
- 避免创建重复的RDD,对于一份RDD,只应创建一个RDD。
- 提高RDD的复用率,当多个RDD数据重叠时,通过提取重复数据进行复用
- 持久化多次重复使用的RDD,用过persist或cache方法,不会从源头重新计算RDD
- 使用高性能算子,reduceByKey代替groupByKey,使用mapPartitions代替map等
- 优化数据结构
开发原则优化比较困难,需要针对不同的场景采用不同的优化方案。可以了解等值连接算法的改进。Spark上的等值连接优化
内存优化
Spark的核心思想就是利用内存作为缓存来实现不同阶段的数据共享,加速程序的执行。一般对于内存的使用效率完全依赖于程序员编写代码的质量。
通过对内存行为的建模与分析以及对代码的语义分析,实现内存策略的自动化。调度器可以识别有价值的RDD放入缓存,根据RDD大小和权重计算,进行操作顺序的优化重拍。使用别的替换算法替代原有的LRU算法及多级缓存模型。通过以上两点优化。
配置参数优化
Spark中共有180个配置参数,用户可以根据自己的需求合理的调整这些配置参数。配置参数对内存分配和使用率、IO开销等有很大的影响。
Executor的内存主要分为3部分:
- 一部分供Task执行用户编写的代码,默认占20%;(用户内存)
- 一部分用于Task通过Shuffle过程去获取一个另一个Stage的输出,然后进行聚合操作,默认20%;(执行内存)
- 最后一部分用于RDD持久化,默认60%。(存储内存)
- 还有一个保留内存,存放Spark内部对象
所谓配置参数的优化,主要是在Spark运行过程中各个使用资源位置调节默认配置参数,进而优化资源的使用率,提高Spark作业的性能。
配置参数优化表
参数 | 参数意义 | 调优建议 |
---|---|---|
num-executors | Executor进程数量 | Executor进程数量的多少直接影响程序的并行度,建议50-100个 |
executor-memory | Executor进程内存 | 4-8GB |
driver-memory | Driver进程内存 | 若使用collect则要考虑增大,以防止内存溢出 |
executor-cores | 每个进程占用的CPU Core数量 | 一般2-4个,每个CPU Core只能执行1个task线程。CPU Core数量越多,越能更快执行完分配的task线程 |
driver-cores | Driver占用的CPU Core数量 | 核心数的多少对程序的并行执行有相当大的影响 |
spark.storage.memoryFraction | 设置RDD持久化数据在Executor内存的占用比 | 默认0.6,若有较多RDD持久化需要提高 |
一种Spark平台性能自动优化方法将参数优化问题转化为机器学习领域的分类问题,提出了一种二分类加多分类的多模型融合方法来实现参数的自动调优。
调度优化
将基于Hadoop MapReduce的调度进行基于Spark特性的相似性改造,将改造后的优化方式应用于Spark平台调度优化。可能会取得不错的改进效果。
许多种基于MapReduce的调度优化。
通常从6个角度来评估调度策略:
- 数据本地化。任务调度时将数据本地化减小网络开销
- Slot粘滞
- 倾斜问题,多数Task执行快,少数Task执行慢
- 饿死问题,采用不公平调度时,一个Task面临不断有优先级更高的Job出现
- 利用率
- 公平性
基于异构Spark集群的自适应任务调度策略HSATS,该策略通过检测节点的负载及资源利用率,分析得到的参数,自适应动态调节节点任务分配的权值,缩短了用户作业的完成时间,提高了异构集群下的资源利用率与服务质量。
Shuffle过程优化
Shuffle在执行过程中会遇到多种问题:
- 处理的数据量会很大,需要将TB、PB级的数据分散到数千的机器上
- 需要保证数据被存放在正确的Partition中,由于数据大于内存,该阶段会有数据从硬盘读到内存中,这个过程会发生多次硬盘读写
- 数据在传输过程中,为了提高传输效率,会对数据压缩处理,解压又占用了大量时间
- 数据的序列化和反序列化也会影响Spark作业的性能。
从三个方面对Shuffle优化进行分析和总结。一、Shuffle过程中发生数据倾斜时的解决方案。二、Shuffle压缩算法的优化。三、Shuffle内存优化。
数据倾斜的解决方案
Shuffle过程中,经常发生数据倾斜问题。什么是数据倾斜,作业在执行过程中,大部分节点的Task执行完毕,部分节点Task执行很慢,导致整个Job执行时间延长。
- 少数几个key对应大量数据,其他key分布均匀。过滤掉导致数据倾斜的key。过滤掉不重要的key。如果重要也不能过滤。
- Shuffle Read Task的默认值大小。提高Shuffle操作的并行度,多个key分配给多个Task。
- join,将reduce join转为map join,前提是大表join小表。
- 两个大表join,将导致倾斜的几个key拆分成独立RDD,添加随机前缀进行join
- RDD大量key因join出现倾斜,添加随机前缀进行join。让多个Task处理相同的key。
数据倾斜的解决只能开发人员结合自身的开发经验,针对不同的场景,选择不同的方案,反复实验。比较难提出一个可以全面优化的方案。
Shuffle压缩算法的优化
Spark Shuffle压缩算法有3种,Snappy,LZ4,LZF。研究并没有给出一个可选择的压缩配置,所有结论均通过样本实验得出,并没有为用户提供一个可以在应用程序运行前进行最优参数配置的压缩策略模型。
Shuffle内存优化
对Shuffle内存优化是目前的研究热点。
- 文献提出可以合并Shuffle的中间结果,提高性能;也可以创建大的Shuffle文件。
- 文献提出针对中间文件,利用列压缩,提高数据传输效率,将结果保存到磁盘上,导致缺失了对迭代的支持
目前重点是Shuffle file如何有效利用内存和内存调度两方面
未来研究方向
开发原则角度,根据不同业务场景,根据侧重优化内容制定对应开发原则。通过数据库和MapReduce的连接方法改进,结合到Spark上。
从内存优化角度,节点之间,任务之间,无法实现内存共享。
配置参数优化角度,从系统运行数据信息挖掘有用信息后对其作出参数优化。尝试将MapReduce运用到Spark。
调度角度,基于MapReduce调度机制研究成果丰富,尝试将其运用到Spark平台上。对原有的FIFO FAIR调度算法改进。
Shuffle过程角度。之前版本Shuffle结果先存储内存,会发生GC,后面新版本,Shuffle中间结果写入磁盘。生成一个单独文件。但是太多小文件,后门引入File Consolidation合并小文件为大文件。
个人感想
可以研究连接方式的改进,结合Spark达到开发原则优化。配置参数优化,需要有一个大系统,获取系统信息,来达到配置优化辅助。调度,结合MapReduce,如何修改调度,如何评估调度比较难。Shuffle压缩,可以有一个压缩策略,运行前获得有效的最佳压缩策略算法。Shuffle内存存在问题,作业不能分配到充分资源而一直等待。修改FAIR方式,采用别的方案。