设为首页 收藏本站
查看: 1197|回复: 0

[经验分享] [大牛翻译系列]Hadoop(6)MapReduce 排序:总排序(Total order sorting)

[复制链接]

尚未签到

发表于 2015-7-14 10:17:58 | 显示全部楼层 |阅读模式
4.2.2 总排序(Total order sorting)
  有的时候需要将作业的的所有输出进行总排序,使各个输出之间的结果是有序的。有以下实例:


  • 如果要得到某个网站中最受欢迎的网址(URL),就需要根据某种受欢迎的指标来对网址进行排序。
  • 如果要让最活跃的用户能够看到某张表,就需要根据某种标准(发表文章数)对用户进行排序。
  
  技术22 在多个reduce间对键进行排序
  在MapReduce框架中,map的输出会被排序,然后被发送给reduce。不过,相同reduce的输入数据是有序的,不同reduce的输入数据就没有顺序关系了。如果要让不同的reduce的数据也存在顺序关系,就需要使用分区器(partitioner)。MapReduce的默认分区器是HashPartitioner。它使用map的输出键的哈希值进行分区。这保证了相同的map输出键的所有记录会到达同一个reduce。不过HashPartitioner并不会对所有map的全部输出键进行总排序。接下来说明如何在MapReduce中对所有map的全部输出键进行排序:
  
  问题
  需要对作业输出的所有键进行总排序,但是不能增加任何一个reduce的负担。
  
  方案
  这里要用到TotalOrderPartitioner类来保证所有reduce的全部输出是有序的。这个类由Hadoop自带。这个分类器保证了所有map的全部输出是完全有序的。那么只要reduce的输出键和输入键是一样的,作业的最终输出就是有序的。
  
  讨论
  TotalOrderPartitioner是Hadoop的内置分区器。它根据分区文件进行分区。分区文件是一个包括N-1个键的预先计算好的序列文件。(N是指reduce的个数。)分区文件中的键的顺序是由map输出键比较器决定的。每一个键对应着一个逻辑区间。TotalOrderPartitioner检查每一个输出键,确定它在那个区间,然后将这个键发送给相对应的reduce。
  图4.15中说明了这个技术的两个部分。第一部分,创建分区文件。第二部分,将TotalOrderPartitioner加入MapReduce作业。
  
DSC0000.jpg
  
  先用InputSampler从输入文件中抽样,以生成分区文件。抽样器可以选用RandomSampler类进行随机抽样,也可以选用IntervalSampler类进行间距为R的等距抽样。生成的分区文件中将包含有序的N-1个键。N是reduce的个数。InputSampler不是MapReduce作业。它从InputFormat读取数据。它在被调用的过程中生成分区。
  下列代码说明了在调用InputSampler函数之前需要完成的步骤:
  



1 int numReducers = 2;
2
3 Path input = new Path(args[0]);
4
5 Path partitionFile = new Path(args[1]);
6
7 InputSampler.Sampler sampler = new InputSampler.RandomSampler(0.1, 10000, 10);
8
9 JobConf job = new JobConf();
10
11 job.setNumReduceTasks(numReducers);
12
13 job.setInputFormat(KeyValueTextInputFormat.class);
14
15 job.setMapOutputKeyClass(Text.class);
16
17 job.setMapOutputValueClass(Text.class);
18
19 TotalOrderPartitioner.setPartitionFile(job, partitionFile);
20
21 FileInputFormat.setInputPaths(job, input);
22
23 InputSampler.writePartitionFile(job, sampler);
  
  下一步在作业中指定TotalOrderPartitioner为分区器:
  



1 job.setPartitionerClass(TotalOrderPartitioner.class);
  
  这个技术并不需要修改MapReduce作业本身,也就是说,不需要修改map或reduce过程。现在就可以开始运行代码了:
  



$ hadoop fs -put test-data/names.txt names.txt
$ bin/run.sh com.manning.hip.ch4.sort.total.TotalSortMapReduce \
names.txt \
large-names-sampled.txt \
output
$ hadoop fs -ls output
/user/aholmes/output/part-00000
/user/aholmes/output/part-00001
$ hadoop fs -cat output/part-00000 | head
AABERG
AABY
AADLAND
$ hadoop fs -cat output/part-00000 | tail
LANCZ
LAND
LANDA
$ hadoop fs -cat output/part-00001 | head
LANDACRE
LANDAKER
LANDAN
$ hadoop fs -cat output/part-00001 | tail
ZYSK
ZYSKOWSKI
ZYWIEC
  
  从MapReduce作业的结果中可以看到,在各个输出文件之间,map的输出键是有序的。
  
  小结
  这个技术中使用InputSampler来创建分区文件。TotalOrderPartitioner使用这个分区文件来分区map的输出键。
  MapReduce也可以生成分区文件,但效率不高。另一个有效的的方法就是用自定义的InputFormat类来执行抽样,并将抽样后的键发送给一个reduce,由其创建分区文件。这也就是这一章下一个部分讲到的抽样。
  
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-86582-1-1.html 上篇帖子: Hadoop中FileSystem的append方法 下篇帖子: SQL Server 2012将与Hadoop无缝集成
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表