-
Apache Hadoop[1](包含HDFS和mapreduce两个核心组件,本文只考虑mapreduce,因此在没有特殊说明情况下Hadoop和mapreduce等价使用)是谷歌公司提出的mapreduce编程模式的开源版本,得到了学术界、工业界的大力支持。随着mapreduce应用规模不断扩大,为Hadoop集群分配合理的资源以及优化mapreduce应用的运行性能一直是研究热点[2]。Hadoop官方路线图规划在Hadoop3.0版本中增加了内存自动预测机制[3]。
已有大量研究工作关注mapreduce性能与配置参数的关系。这些研究的核心思想是通过构建性能模型获得特定作业在某个配置下的运行时间,然后使用优化算法获得最优的配置参数。文献[4]使用基于代价的方式构建性能模型[5],使用递归随机搜索算法找到优化的配置参数。文献[6]的性能模型与文献[4]类似,但使用的是遗传算法寻找最优配置参数。文献[7]未构建性能模型,通过修改hadoop框架在线获得任务运行时间,使用拉丁超立方体抽样方法进行配置参数采样,使用智能爬山算法搜索最优配置参数。这些研究存在以下不足:1)构建性能模型增加了不必要的复杂度;2)搜索算法需要限定内存资源配置参数的搜索空间,增加用户使用难度。
Hadoop应用程序运行在Java虚拟机之上,JVM的配置对Hadoop应用的性能和稳定性有直接影响。文献[8]通过定期采样作业的内存使用量来预测内存的使用,没有说明预测的内存配置是否提升作业性能。文献[9]通过随机森林算法优化JVM配置,但给出的优化配置的年轻代与年长代比例仅有1:2与1:8这两种配置。文献[10-11]没有考虑mapreduce作业的特殊性,也没有给出JVM内存大小的建议。
为解决这些问题,根据JVM分代内存管理原理,结合年轻代和年长代对mapreduce作业性能影响不同,提出分代内存预测方法,具体包括:
1)使用回归模型建模年轻代垃圾回收平均暂停时间,将寻找合理的年轻代大小问题转换为非线性优化问题,并设计求解算法;
2)分析map任务和reduce任务的性能与内存配置的关系,建立内存模型,通过内存模型求解年长代内存需求。不需要构建性能模型和使用优化算法,也不需要用户指定内存范围。
HTML
-
Hadoop测试集群有8个从节点,每个从节点分配5 GB内存,排他性使用一个E5-2609@2.4GHz的物理核。每个从节点分配2个map任务槽和1个reduce任务槽,Hadoop以apache发布版本1.2.1为基础,修改了reduce任务内存管理,修改日志保存机制。本文选择PUMA测试套件[14]的wordcount (WD)、invertedindex (ID)、TeraSort (TS)、adjlist (ADJ)这4个测试程序。wordcount、invertedindex测试程序的输入数据为多个文件组成的10 GB wikipedia数据集。adjlist输入数据集为从图数据集中随机选出10 GB数据。TeraSort输入数据使用mapreduce提供的程序自动生成,总共10 GB左右。
-
使用loess[15]对WD、ID、TS、ADJ的map任务和reduce任务的minor GC进行回归建模。使用算法1预测的年轻代大小进行测试,统计了4种测试程序的所有map和reduce任务GC暂停时间占任务运行时间的百分比,如图 3所示。可得知除WD和ADJ的reduce任务的GC暂停时间的比例大于1%以外,其他任务的GC暂停时间均小于1%。
为避免年轻代分配过大导致不必要的资源浪费,分析了WD的map任务和reduce任务运行时间平均值与年轻代的关系,如图 4所示。
从图 4得知,年轻代为180 MB左右能获得较好的运行性能。ID、TS和ADJ也呈现相似的的特征。图 4中获得的年轻代合理值可以和算法1所得值综合考虑,选择两者的最小值为最终的年轻代大小。
-
统计WD、ID、TS和ADJ的map任务和reduce任务的Smr累计分布函数,其中map任务Smr非常集中,ADJ和TS的reduce任务的Smr也非常集中,WD和ID较分散,但差距也较小,如图 5所示。因此即使采用最大内存需求也不会造成过多内存资源浪费。
pred (即本文提出的内存预测方法)和starfish的优化内存配置对比如表 1所示。从表 1得知pred给出的内存配置均比starfish小。为评价Smr分配是否合理,分别统计了默认配置、starfish和pred这3种配置条件下发生溢写的任务数量,如表 2所示,其中MSC、MNSC、RSC和RNSC分别表示发生溢写的map任务数、未发生溢写的map任务数、发生溢写的reduce任务数和未发生溢写的reduce任务数。未发生溢写是任务获得最佳运行性能的基本条件。从表 1和表 2得知,pred方法能在比starfish更少的内存配置条件下获得最佳的任务执行流程,即未发生溢写操作。
测试程序 starfish pred map/MB reduce/MB map/MB reduce/MB WD 500 4 000 350 2 260 ID 1 200 4 000 350 2 680 TS 500 4 000 250 1 500 ADJ 1 200 4 000 410 2 000 测试程序 MSC MNSC RSC RNSC WD 162|0|0 0|162|162 1|8|0 0|0|8 ID 162|6|0 0|156|162 1|8|0 0|0|8 TS 150|0|0 50|200|200 1|1|0 0|31|8 ADJ 0|0|0 183|183|183 1|16|0 0|0|8 注:表格数据格式为:默认配置|starfish|pred。 -
mapreduce配置参数调优以starfish最为全面,效果最佳。与基于经验的配置参数优化相比,starfish能获得更好的性能提升[4]。在starfish0.3.0版本的基础之上增加了adjlist和invertedindex测试程序的支持,在相同的集群资源下分别比较4种测试程序在默认配置、starfish优化配置和pred配置下的运行时间,结果如图 6所示。starfish和pred给出的配置参数显著提升了作业性能,且pred性能在4种测试程序下均优于starfish。与默认配置相比,starfish在测试集群上平均加速比为3.5,最大加速比为6.1。与默认配置相比,pred的平均加速比为6.4,最大加速比为8。
starfish目前只支持Hadoop0.20版本,要求mapreduce必须使用新API编写。pred只需要作业的历史记录文件和任务JVM输出的垃圾回收日志,mapreduce的各个版本均支持通过简单配置获得这些数据,因此从部署难度及适应Hadoop版本更新两个方面讲,pred比starfish更易于使用。
文献[16-17]表明,在facebook、雅虎和淘宝的Hadoop生产集群中,绝大部分的mapreduce作业的输入数据只是GB级别,当前的Hadoop集群内存资源足够将这些待处理的数据全部缓存在内存中。对于这种数据规模的mapreduce作业,pred能提供很好的性能优化。