写这篇文章,是因为最近遇到了mapreduce的二次排序问题。以前的理解不完全正确。首先看一下mapreduce的过程

相信这张图熟悉MR的人都应该见过,再来一张图

wordcount也不细说了,hadoop里面的hello,world

之前我的理解是map过来的<k,v>会形成(k,<v1,v2,v3...>)的格式,并且按照这种思路写出来不少的mapreduce程序,而且没有错。

后来自定义Writable对象,封装一组值作为key,也没有什么问题,而且一直认为key只要在compareTo中重写 了方法就万事大吉,而且compareTo返回0的会作为相同的key。误区就在这里,之前一直认为key相同的value会合并到一个"list"中-。这句话就有错,key是key,value是value,根本不会将key对应的value合并在一起,真实情况是默认将key相同(compareTo返回0的)的合并成了一组,在组相同的里面去foreach里面的value,如果是自定义key的话你可以将key打印一下,或发现key并不相同。

上代码:

  1. public class Entry implements WritableComparable<Entry> {
  2. private String yearMonth;
  3. private int count;
  4.  
  5. public Entry() {
  6. }
  7.  
  8. @Override
  9. public int compareTo(Entry entry) {
  10. int result = this.yearMonth.compareTo(entry.getYearMonth());
  11. if (result == 0) {
  12. result = Integer.compare(count, entry.getCount());
  13. }
  14. return result;
  15. }
  16.  
  17. @Override
  18. public void write(DataOutput dataOutput) throws IOException {
  19. dataOutput.writeUTF(yearMonth);
  20. dataOutput.writeInt(count);
  21. }
  22.  
  23. @Override
  24. public void readFields(DataInput dataInput) throws IOException {
  25. this.yearMonth = dataInput.readUTF();
  26. this.count = dataInput.readInt();
  27. }
  28.  
  29. public String getYearMonth() {
  30. return yearMonth;
  31. }
  32.  
  33. public void setYearMonth(String yearMonth) {
  34. this.yearMonth = yearMonth;
  35. }
  36.  
  37. public int getCount() {
  38. return count;
  39. }
  40.  
  41. public void setCount(int count) {
  42. this.count = count;
  43. }
  44.  
  45. @Override
  46. public String toString() {
  47. return yearMonth;
  48. }
  49. }

自定义分区 EntryPartitioner.java

  1. public class EntryPartitioner extends Partitioner<Entry, Text> {
  2.  
  3. @Override
  4. public int getPartition(Entry entry, Text paramVALUE, int numberPartitions) {
  5. return Math.abs((entry.getYearMonth().hashCode() % numberPartitions));
  6. }
  7. }

自定义分组

  1. public class EntryGroupingComparator extends WritableComparator {
  2. public EntryGroupingComparator() {
  3. super(Entry.class, true);
  4. }
  5.  
  6. @Override
  7. public int compare(WritableComparable a, WritableComparable b) {
  8. Entry a1 = (Entry) a;
  9. Entry b1 = (Entry) b;
  10. return a1.getYearMonth().compareTo(b1.getYearMonth());
  11. }
  12. }

mapper类

  1. public class SecondarySortMapper extends
  2. Mapper<LongWritable, Text, Entry, Text> {
  3.  
  4. private Entry entry = new Entry();
  5. private Text value = new Text();
  6.  
  7. @Override
  8. protected void map(LongWritable key, Text lines, Context context)
  9. throws IOException, InterruptedException {
  10. String line = lines.toString();
  11. String[] tokens = line.split(",");
  12. String yearMonth = tokens[0] + "-" + tokens[1];
  13. int count = Integer.parseInt(tokens[2]);
  14.  
  15. entry.setYearMonth(yearMonth);
  16. entry.setCount(count);
  17. value.set(tokens[2]);
  18. context.write(entry, value);
  19.  
  20. }
  21. }

reducer类

  1. public class SecondarySortReducer extends Reducer<Entry, Text, Entry, Text> {
  2. @Override
  3. protected void reduce(Entry key, Iterable<Text> values, Context context)
  4. throws IOException, InterruptedException {
  5. System.out.println("-----------------华丽的分割线-----------------");
  6. StringBuilder builder = new StringBuilder();
  7. for (Text value : values) {
  8. System.out.println(key+"==>"+value);
  9. builder.append(value.toString());
  10. builder.append(",");
  11. }
  12. context.write(key, new Text(builder.toString()));
  13. }
  14. }

reducer中打印出来的跟原来想的不一样,一组的值除了自定义分组的属性相同外,其他的属性有不同的。看来以前是自己理解不够深入啊,特此写出,以示警戒

 

重新认识mapreduce的更多相关文章

  1. Mapreduce的文件和hbase共同输入

    Mapreduce的文件和hbase共同输入 package duogemap;   import java.io.IOException;   import org.apache.hadoop.co ...

  2. mapreduce多文件输出的两方法

    mapreduce多文件输出的两方法   package duogemap;   import java.io.IOException;   import org.apache.hadoop.conf ...

  3. mapreduce中一个map多个输入路径

    package duogemap; import java.io.IOException; import java.util.ArrayList; import java.util.List; imp ...

  4. Hadoop 中利用 mapreduce 读写 mysql 数据

    Hadoop 中利用 mapreduce 读写 mysql 数据   有时候我们在项目中会遇到输入结果集很大,但是输出结果很小,比如一些 pv.uv 数据,然后为了实时查询的需求,或者一些 OLAP ...

  5. [Hadoop in Action] 第5章 高阶MapReduce

    链接多个MapReduce作业 执行多个数据集的联结 生成Bloom filter   1.链接MapReduce作业   [顺序链接MapReduce作业]   mapreduce-1 | mapr ...

  6. MapReduce

    2016-12-21  16:53:49 mapred-default.xml mapreduce.input.fileinputformat.split.minsize 0 The minimum ...

  7. 使用mapreduce计算环比的实例

    最近做了一个小的mapreduce程序,主要目的是计算环比值最高的前5名,本来打算使用spark计算,可是本人目前spark还只是简单看了下,因此就先改用mapreduce计算了,今天和大家分享下这个 ...

  8. MapReduce剖析笔记之八: Map输出数据的处理类MapOutputBuffer分析

    在上一节我们分析了Child子进程启动,处理Map.Reduce任务的主要过程,但对于一些细节没有分析,这一节主要对MapOutputBuffer这个关键类进行分析. MapOutputBuffer顾 ...

  9. MapReduce剖析笔记之七:Child子进程处理Map和Reduce任务的主要流程

    在上一节我们分析了TaskTracker如何对JobTracker分配过来的任务进行初始化,并创建各类JVM启动所需的信息,最终创建JVM的整个过程,本节我们继续来看,JVM启动后,执行的是Child ...

  10. MapReduce剖析笔记之六:TaskTracker初始化任务并启动JVM过程

    在上面一节我们分析了JobTracker调用JobQueueTaskScheduler进行任务分配,JobQueueTaskScheduler又调用JobInProgress按照一定顺序查找任务的流程 ...

随机推荐

  1. sso demo 取消https (cas)

    基本配置 参考之前得随笔  http://www.cnblogs.com/rocky-fang/p/5354947.html 1. 修改tomcat-cas 配置 1.1 在 D:\test\sso\ ...

  2. MYSQL 练习

    导出现有数据库数据: mysqldump -u用户名 -p密码 数据库名称 >导出文件路径           # 结构+数据 mysqldump -u用户名 -p密码 -d 数据库名称 > ...

  3. ahjesus code simith 存储过程模板

    <%------------------------------------------------------------------------------------------ * Au ...

  4. 【LoadRunner】OSGI性能测试实例

    其实我们就两点 Ø  确定测试登录最大并发用户数:Ø  事务平均响应时间 (两个查询) 得到这个任务 如何展开测试工作呢? 一.WindowsResources 设置(其实不监控 设不设都行 我感觉) ...

  5. NotSerializableException解决方法

    NotSerializableException 问题描述: 想要写入对象的时候的时候回抛出NotSerializableException:类名 原因: 写入的对象没有序列化,即没有实现java.i ...

  6. Lua-泛型for循环 pairs和ipairs的区别

    先看一段简单的代码: local mytable = { , , aa = "abc", subtable = {}, , } --for循环1 print("for - ...

  7. jQuery自定义漂亮的下拉框插件8种效果演示

    原始的下拉框不好看这里推荐一个jQuery自定义漂亮的下拉框插件8种效果演示 在线预览 下载地址 实例代码 <!DOCTYPE html> <html lang="en&q ...

  8. jQuery BreakingNews 间歇滚动

    BreakingNews 是一款基于jQuery的间歇滚动插件.它可以设置标题.标题颜色.标题背景颜色.链接颜色.字体大小.边框.宽度.自动滚动.间歇时间等等,同时它还好提供两种过度方式--淡入淡出( ...

  9. 众人口中的JAVASCRIPT

    目前所说的JAVASCRIPT=ECMAscript+DOM+BOM DOM全称:Document Object Model,造作网页内容的标准. BOM全称:Browse Object Model, ...

  10. angularjs——插值字符串

    一.何为插值字符串? 其实插值字符串的意思就是:拥有字符插值标记的字符串.如: hello,{{ to }}....字符插值标记:相当于我们平时在字符串替换中使用到的占位符.上面的例子中的{{to}} ...