MapReduce计算框架中的高性能排序方法

文档序号:6543485阅读:541来源:国知局
MapReduce计算框架中的高性能排序方法
【专利摘要】本发明涉及一种MapReduce计算框架中的高性能排序方法。该方法在Map阶段按照partition分别构建缓冲链,移除partition本身进行排序的需要,并且对于每一个partition数据将按照块进行组织,降低了数据在内存中的拷贝以及文件IO方面的代价;在Map阶段不执行排序操作,在Reduce阶段以一个较大的缓冲池作为一次排序的基本单位,使得在排序的归并阶段总的归并路数是一个用户可调优的值。本发明通过一种混合的内存排序算法,优化了MapReduce框架中排序的两个阶段,基本消除了排序对于计算框架的性能影响,进而提升了计算框架的资源有效性,降低了集群的整体资源消耗。
【专利说明】MapReduce计算框架中的高性能排序方法
【技术领域】
[0001]本发明属于信息【技术领域】,涉及一种对分布式计算框架的优化方法,特别涉及一种在MapReduce计算框架中提高排序性能的方法。
【背景技术】
[0002]MapReduce是分布式计算中的一种标准框架,但在资源消耗方面,现有MapReduce框架并不高效,导致大量集群资源被浪费。
[0003]现有MapReduce框架中需要对中间数据的key/value对进行排序,并且排序构成了现有计算框架中主要的资源消耗。我们以MapReduce的开源实现hadoop为例,说明上述问题。
[0004]如图1所示,为传统MapReduce数据流程示意图。其中Hadoop文件系统(简称HDFS,Hadoop File System)负责数据的分布式存储。计算框架所执行任务(Job)从HDFS读入数据经过处理后再写入到HDFS。在计算框架内部分为Map和Reduce两个阶段,Map阶段将HDFS上的数据执行用户自定义的Map函数,然后对输出的中间数据首先放入内存,然后排序后写入本地磁盘。在Reduce阶段,每个Reduce接收来自各个Map的排序后的中间数据然后进行归并。框架对同一 key下的所有value调用用户自定义的Reduce函数进行计算后写入到HDFS。具体的数据流程可以参见图1。
[0005]在如图1所示的原有的数据流程中,排序所需要的工作量3,5,7,8消耗了大部分的框架CPU资源。这种消耗又可以分为内存排序和多路归并两个阶段。
[0006]1、流程3中对中间数据进行基于内存的二级索引快速排序。排序的过程实际上是对16字节的索引进行排序,索引为一个四元组〈id, partition, key offset, valueoffset〉。当两个这样的四元组进行比较时首先比较两条记录的partition,构成一个partition 升序的序列。只有当 partition—致时再根据〈key offset, value offset〉找到对应的key进行字节比较。大量冗余的partition比较以及O(nlogn)复杂度的代价使得这一部分效率很低。
[0007]2、流程5,7,8中对内存或磁盘上的有序数据进行多路归并排序。由于在MapReduce计算框架中需要保证内存有限时对数据依旧可以处理,因此基于磁盘的归并排序是框架必不可少的一部分。这一部分的算法实现的复杂度为O(nlogm),其中η为记录数而m为归并路数。由于整体所需要排序的记录数固定,因此这一部分是否高效取决于归并路数,而归并路数在现有实现中其最小值和map的数目相当。对于map数目较大的Job,这部分的代价会高于第一部分的代价并消耗大部分资源。
[0008]因此,在现有MapReduce计算框架中进行排序的两个阶段因为算法的选择或是处理流程上的不当导致都不高效,而排序操作又对于每一个Job都必不可少,造成了大量的资源浪费。

【发明内容】
[0009]本发明目的在于提出一种在MapReduce计算框架中进行的高性能排序方法,能够降低框架整体的CPU资源消耗,提高集群整体有效利用率。
[0010]本发明的MapReduce计算框架中的高性能排序方法,其步骤包括:
[0011]1、Map Task从HDFS上读取文件,构造输入数据的key/value对;
[0012]2、对输入数据执行用户自定义Map函数并输出中间结果的key/value对,并计算key所对应的partition ;对内存中每个partition设置对应的缓冲链,将中间结果的key/value对首先计算长度,然后插入到缓冲链中;
[0013]3、当内存无法放下所有中间结果的key/value对时,按照partition的顺序,输出所有缓冲链到本地文件;
[0014]4、对经过上述步骤后在内存和本地磁盘上形成的一个或多个未排序的结果按照partition的顺序进行归并,输出成一个完整的按照partition进行分段的本地文件;
[0015]5、Reduce Task通过AppMaster获得Map Task结束的信息,向负责该Map数据托管的进程发送http请求,拖取该Map输出的中间数据中属于该Reduce的部分,将这些数据根据其大小选择放于内存或放于本地磁盘;
[0016]6、将内存或磁盘中的中间数据读入内存中的排序缓冲池,当排序缓冲池满时,对整个缓冲池进行排序;
[0017]7、对于中间数据无法全部放在一个排序缓冲池中的情况,在排序后将数据写出到本地文件中。
[0018]进一步地,上述方法还包括如下步骤:
[0019]8、对内存和本地文件中的有序结果进行归并,归并结果作为用户自定义Reduce函数的输入;
[0020]9、Reduce函数对相同key下的所有value执行操作,生成输出数据的key/value对并写入HDFS。
[0021]进一步地,步骤6)对于大多数作业使用的整形或者字符数组类型的key,抽取key中能够保序的4字节作为低32位,和该条记录本身4字节的二级索引作为高32位进行拼接,形成一个8字节的长整形作为新的key。更进一步地,在这个8字节上使用基数排序,使得其从key中抽取的4字节有序。更进一步地,获取基数排序后的二级索引,再对其进行快速排序保证整体记录的有序性。
[0022]进一步地,步骤6)对于无法抽取保序4字节的key类型,构建二级索引,使用快速排序进行整体记录的排序。
[0023]其中,抽取key中4字节的方法是:对于整数即其本身;对于字符数组类型的key为其排序序列的前4个字节,以整数对待,并在最高位取反。
[0024]其中,基数排序算法为非递归版本,输入为两个长整形的数组,一个用于存放原始数据,一个用于算法的临时空间,算法执行后的结果为长整形数组中低32位整形有序。
[0025]其中,缓冲池的大小和原有实现(图1所示方法)中的排序缓冲池的大小保持一致,需要用户设定。
[0026]本发明的有益效果如下:
[0027]1、本发明在Map阶段按照partition分别构建缓冲链,移除了 partition本身进行排序的需要,并且对于每一个partition数据将按照块(block)进行组织,降低了数据在内存中的拷贝以及文件IO方面的代价。
[0028]2、本发明在Map阶段不执行排序操作,使得Map阶段的运行时间和CPU资源消耗大幅度下降,进而整体Map阶段的结束时间提前,并且对于大多数作业的整体运行时间得到优化。
[0029]3、本发明在Reduce阶段以一个较大的缓冲池作为一次排序的基本单位(例如128MB),使得在排序的归并阶段总的归并路数是一个用户可调优的值。对于每个reduce处理数据量一定的情况,归并路数为一个非常小的常数值(一般为I?4)。因此归并阶段的算法复杂度和消耗的资源都将减少。
[0030]4、本发明通过一种混合的内存排序算法,能够高效的对内存中变长记录进行排序。基数排序算法复杂度低但不适合变长字段,快速排序适用性广但算法复杂度高。结合MapReduce框架场景需要对大量变长的〈key,value)格式的数据进行排序,本发明首先通过低复杂度的基数排序将记录的定长部分进行排序,然后对于少量无序的记录再利用快速排序来保证结果的正确性。两种算法的混合使得既能保证整体的低算法复杂度,又能保证对变长记录的适用性,提高了整体的排序性能。
[0031]因此,本发明优化了 MapReduce框架中排序的两个阶段,使用高效的内存算法并且降低归并路数使得整体的排序性能得到大幅度提升,基本消除了排序对于计算框架的性能影响,进而提升了计算框架的资源有效性,降低了集群的整体资源消耗。
【专利附图】

【附图说明】
[0032]图1传统MapReduce计算框架数据流程图。
[0033]图2本发明MapReduce计算框架数据流程图。
[0034]图3本发明内存排序方法流程图。
[0035]图4本发明数据流程与传统数据流程性能对比图。
[0036]图5本发明混合内存排序算法和传统快速排序性能对比图。
[0037]图6本发明高性能排序方法和传统框架中排序的资源消耗对比图。
【具体实施方式】
[0038]下面通过具体实施例和附图,对本发明做进一步说明。
[0039]本发明是在Hadoop平台版本2.2上进行的,主要针对MapReduce计算框架中的数据流程进行优化。图2是本发明MapReduce计算框架数据流程图。我们分为两个部分说明实施方式,首先说明为了减少归并路数将Map阶段的排序移至Reduce阶段的新数据流程,接着说明混合的高性能内存排序算法的实现细节。
[0040]本发明重新设计了 MapReduce计算框架的数据流程。本发明的工作基于Hadoop进行说明,但本发明对于排序方案的优化也涵盖其它MapReduce架构的系统。
[0041]对于Map阶段,本发明重新设计了 MapOutputBuffer的实现。原始的MapOutputBuffer的功能为接收中间数据三元组〈key, value, partition〉,并最终在本地文件系统上形成一个排序后的文件。但在本发明中MapOutputBuffer的输入不变,但输出为一个文件系统上的未排序文件。
[0042]本发明中MapOutputBuffer对每个partition维护一个缓冲链,缓冲链上的缓冲块来自于一个共享的缓冲池,在分配过程中,每个缓冲链向缓冲池申请一个偏移来锁定一块内存区域。对于每一个输入的三元组,会根据partition确定将要添加到的缓冲链,然后首先将〈key,value)序列化得到长度,然后添加到该缓冲链的最后。一次添加可能会跨越某个缓冲链上的多个缓冲块。
[0043]在每次添加到缓冲链前会做一次检查,确保有足够的空间。对于内存不足以容纳所有中间数据的情况,我们把所有的缓冲链按照partition的顺序写入到一个本地的临时文件。
[0044]在所有输入都已经添加之后,我们需要合并内存和临时文件的数据来形成最终的本件,这种合并将以partition为单位,因此进行合并的次数非常少。而在传统实现中如果中间数据的条数非常多则会造成额外的代价。
[0045]本发明对于Reduce阶段的设计主要是增加一个大的排序缓冲池用来做内存排序。原有实现中,当Map阶段所有排序的数据传输到Reduce端时会根据大小放在内存或本地磁盘上,每一个这样的有序数据块称为一个Segment。而在本发明中,传输的数据块为未排序的,因此我们需要把每一条记录都添加到内存的一个大的缓冲区中,只有当缓冲区无法容纳更多记录时,我们对其进行排序,然后将排序后的内容写出到本地磁盘,形成和原有实现中格式类似的Segment。
[0046]将传输的内容添加到排序缓冲池中的操作必须保证不能阻塞,因此在本发明中我们采用双缓冲结构,当某一个排序缓冲满了之后,我们会异步的进行排序并写出,同时另一个排序缓冲会继续接受传输的数据。这种方式很好地并行化了数据通过网络传输的时间以及数据经过排序写入本地磁盘的时间。
[0047]当所有Segment都构建完成后,会在本地磁盘上形成少数待归并的有序文件,此时构建内存的堆结构来执行多路归并的操作。
[0048]图3是对本发明中使用的内存排序算法的描述,样例中记录key为字符数组类型。
[0049]首先在填充排序缓冲池(Sort Buffer (byte []))的时候,会通过一个Hash函数来对每个key得到一个整形的返回值。Hash函数的描述可以参考http://en.wikipedia.0rg/wiki/Hash_function。对于大多数key类型,hash函数为系统自带,保证了最终的结果和传统MapReduce —致。对于某些key类型,因为难以定制保序的Hash函数,用户可以选择是否放弃结果集的有序性来提升性能。这种情况下,用户需要自定义Hash函数或者使用系统自带通用的 MurMurHash (http://en.wikipedia.0rg/wiki/MurmurHash)。
[0050]得到的整形值会和这个记录在缓冲池中的位置进行拼接,构成一个长整形数组(Index(long[]) )0对于数组的直接的排序操作会比在二级索引上操作更高效。对于这个长整形数组的基数排序算法(Radix sort)只需要保证低4个字节的有序性,当排序完成后高4个字节所代表的索引就是对应记录应该在整个记录集中的大致位置。我们将高4字节提取出来得到整形数组。
[0051]因为我们只截取了 key的一部分信息用于排序,因此有可能有部分不同的key但通过Hash函数后得到相同的值。所以我们需要遍历长整形数组中的低4字节,如果有相同值,我们需要对提取出来的整形数组的对应区域进行额外的一次快速排序(Quick sort)。由于在第一次排序中数据已经基本有序,因此第二次排序所需要比较的key的数目会非常少,所以代价也非常低。[0052]本发明在已有的hadoop基准数据集上进行了测试来验证,共分为三个部分。第一个测试使用Terasort的数据集在20台机器的分布式环境中来验证本发明中Reduce端进行排序的数据流相比原有实现中Map端进行排序数据流的性能优势。试验测试了在不同数据量上排序部分的时间差异,我们采用了对数坐标系,并且我们将Map端排序的理论最优值归一化为I。结果如图4所示,从中可以看到当数据量增大时,Reduce端进行排序得到的性能效率明显提升,排序时间上的差异接近3倍。
[0053]第二个测试我们验证本发明采用的混合内存排序算法相比于单一的快速排序算法性能优势。该测试我们采用单机的测试环境,使用了通用的排序数据集。实验结果如图5所示,在一些比较大的数据集上,两种算法的性能差异接近10倍。在实际生产环境中,一次排序的数据集大小一般都在100MB以上,因此采用混合的内存排序算法对于降低整体框架的排序资源消耗优势显著。
[0054]第三个测试在20台机器的分布式环境下验证本发明两种高性能排序方法的结合在不同作业类型下的表现。我们使用了 HiBench (https://github.com/intel_hadoop/HiBench)基准测试集进行验证。我们将排序在框架中的资源消耗作为对比项,结果如图6所示,本发明中的高性能排序方法能够将大多数作业中排序部分的资源消耗降到5%以内,使得排序部分不再成为集群资源消耗的主要来源。
[0055]以上实施例仅用以说明本发明的技术方案而非对其进行限制,本领域的普通技术人员可以对本发明的技术方案进行修改或者等同替换,而不脱离本发明的精神和范围,本发明的保护范围应以权利要求所述为准。
【权利要求】
1.一种MapReduce计算框架中的高性能排序方法,其步骤包括: 1)Map Task从HDFS上读取文件,构造输入数据的key/value对; 2)对输入数据执行用户自定义Map函数并输出中间结果的key/value对,并计算key所对应的partition ;对内存中每个partition设置对应的缓冲链,将中间结果的key/value对首先计算长度,然后插入到缓冲链中; 3)当内存无法放下所有中间结果的key/value对时,按照partition的顺序,输出所有缓冲链到本地文件; 4)对经过上述步骤后在内存和本地磁盘上形成的一个或多个未排序的结果按照partition的顺序进行归并,输出成一个完整的按照partition进行分段的本地文件; 5)Reduce Task通过AppMaster获得Map Task结束的信息,向负责该Map数据托管的进程发送http请求,拖取该Map输出的中间数据中属于该Reduce的部分,将这些数据根据其大小选择放于内存或放于本地磁盘; 6)将内存或磁盘中的中间数据读入内存中的排序缓冲池,当排序缓冲池满时,对整个缓冲池进行排序; 7)对于中间数据无法全部放在一个排序缓冲池中的情况,在排序后将数据写出到本地文件中。
2.如权利要求1所述的方法,其特征在于,还包括如下步骤: 8)对内存和本地文件中的有序结果进行归并,归并结果作为用户自定义Reduce函数的输入; 9)Reduce函数对相同key下的所有value执行操作,生成输出数据的key/value对并写入HDFS。
3.如权利要求1或2所述的方法,其特征在于:步骤6)对于大多数作业使用的整形或者字符数组类型的key,抽取key中能够保序的4字节作为低32位,和该条记录本身4字节的二级索引作为高32位进行拼接,形成一个8字节的长整形作为新的key。
4.如权利要求3所述的方法,其特征在于:在所述8字节上使用基数排序,使得其从key中抽取的4字节有序。
5.如权利要求3所述的方法,其特征在于:所述基数排序算法为非递归版本,输入为两个长整形的数组,一个用于存放原始数据,一个用于算法的临时空间,算法执行后的结果为长整形数组中低32位整形有序。
6.如权利要求3所述的方法,其特征在于:获取基数排序后的二级索引,再对其进行快速排序保证整体记录的有序性。
7.如权利要求3所述的方法,其特征在于:抽取key中4字节的方法是:对于整数即其本身;对于字符数组类型的key为其排序序列的前4个字节,以整数对待,并在最高位取反。
8.如权利要求3所述的方法,其特征在于:步骤6)对于无法抽取保序4字节的key类型,构建二级索引,使用快速排序进行整体记录的排序。
9.如权利要求1或2所述的方法,其特征在于,步骤6)采用双缓冲结构将传输的内容添加到排序缓冲池中,以避免阻塞:当某一个排序缓冲满后,异步地进行排序并写出,同时另一个排序缓冲继续接收传输的数据。
【文档编号】G06F17/30GK103995827SQ201410145069
【公开日】2014年8月20日 申请日期:2014年4月10日 优先权日:2014年4月10日
【发明者】蒋达晟, 陈薇, 王腾蛟 申请人:北京大学
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1