1TB(或1分钟)排序的冠军  
作为分布式数据处理的框架,集群的数据处理能力究竟有多快?或许1TB排序可以作为衡量的标准之一。  1TB排序,就是对1TB(1024GB,大约100亿行数据)的数据进行排序。2008年, Hadoop赢得1TB排序基准评估第一名 ,排序1TB数据耗时209秒。后来, 1TB排序被1分钟排序所取代 ,1分钟排序指的是在一分钟内尽可能多的排序。 2009年,在一个1406个节点组成的hadoop集群,在59秒里对500GB完成了排序;而在1460个节点的集群,排序1TB数据只花了62秒 。  这么惊人的数据处理能力,是不是让你印象深刻呢?呵呵 

TeraSort 例子分为3个模块:

1. TeraGen,用于生成排序的原始数据。

2. TeraSort, 用于完成对原始数据的排序工作。

3. TeraValida, 用于完成对排序结果的验证。





1. TeraGen生成什么样的数据?


1TB的数据?100亿条数据?都是什么样的数据呢?让我们来看几条: 


1. .t^#\|v$2\         0AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDEEEEEEEEEEFFFFFFFFFFGGGGGGGGGGHHHHHHHH  
2. 75@~?'WdUF         1IIIIIIIIIIJJJJJJJJJJKKKKKKKKKKLLLLLLLLLLMMMMMMMMMMNNNNNNNNNNOOOOOOOOOOPPPPPPPP  
3. w[o||:N&H,         2QQQQQQQQQQRRRRRRRRRRSSSSSSSSSSTTTTTTTTTTUUUUUUUUUUVVVVVVVVVVWWWWWWWWWWXXXXXXXX  
4. ^Eu)<n#kdP         3YYYYYYYYYYZZZZZZZZZZAAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDEEEEEEEEEEFFFFFFFF  
5. +l-$$OE/ZH         4GGGGGGGGGGHHHHHHHHHHIIIIIIIIIIJJJJJJJJJJKKKKKKKKKKLLLLLLLLLLMMMMMMMMMMNNNNNNNN  
6. LsS8)|.ZLD         5OOOOOOOOOOPPPPPPPPPPQQQQQQQQQQRRRRRRRRRRSSSSSSSSSSTTTTTTTTTTUUUUUUUUUUVVVVVVVV  
7. le5awB.$sm         6WWWWWWWWWWXXXXXXXXXXYYYYYYYYYYZZZZZZZZZZAAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDD  
8. q__[fwhKFg         7EEEEEEEEEEFFFFFFFFFFGGGGGGGGGGHHHHHHHHHHIIIIIIIIIIJJJJJJJJJJKKKKKKKKKKLLLLLLLL  
9. ;L+!2rT~hd         8MMMMMMMMMMNNNNNNNNNNOOOOOOOOOOPPPPPPPPPPQQQQQQQQQQRRRRRRRRRRSSSSSSSSSSTTTTTTTT  
10. M^*dDE;6^<         9UUUUUUUUUUVVVVVVVVVVWWWWWWWWWWXXXXXXXXXXYYYYYYYYYYZZZZZZZZZZAAAAAAAAAABBBBBBBB



描述一下:每一行,是一条数据。每一条,由2部分组成,前面是一个由10个随即字符组成的key,后面是一个80个字符组成的value。 



排序的任务:按照key的顺序排。 



那么1TB的数据从何而来?答案是用程序随即生成的,用一个只有map,没有reduce的MapReduce job,在整个集群上先随即生成100亿行数据。然后,在这个基础上,再运行排序的MapReduce job,以测试集群排序性能。 




2. TeraSort的工作原理



先说明一点,熟悉MapReduce的人都知道:排序是MapReduce的天然特性!在数据达到reducer之前,mapreduce框架已经对这些数据按键排序了。 



所以,

在这个排序的job里,不需要特殊的Mapper和Reducer类。用默认的 
IdentityMapper和IdentityReducer
即可。 



既然排序是天然特性,那么1TB排序的难点在哪里呢??答:100亿行的数据随即分散在1000多台机器上,mapper和reducer都是Identity的,这个难点就在MapReduce的shuffle阶段!关键在如何取样和怎么写Partitioner。 



好在这个排序的源代码已近包含在hadoop的examples里了,下面我们就来分析一下。 

在TeraSort源码中提供了两种Partitioner,一种是SimplePartitioner,一种是TotalOrderPartitioner,

SimplePartitioner::GetPartition(),直接对key值的前缀做了一些处理,视乎不能保证特定区域的key值分配到特定的bucket.

TotalOrderPartitioner: 是构建了一个3层的字典树,用key的前两个byte作为查询关键字,查找出以2个byte前缀的key值应该属于哪个bucket,应该由哪个reduce去做排序处理。这样每个reduce的输出结果就不需要再merge了。


下面博文是对teraGen,teraSort, teraValide进行测试的例子:


其中提到的hadoop-0.20.1-examples.jar,在hadoop的release压缩包里就有,也可以自己下源码编译。


参考文献:

http://datacenter.watchstor.com/server-134830.htm