文档章节

Hadoop实战读书笔记(9)

祥林会跟你远走高飞
 祥林会跟你远走高飞
发布于 2014/12/09 12:03
字数 1755
阅读 107
收藏 4
点赞 0
评论 0

如何将一个反向引用索引的程序的Reducer输出的类型改为IntWritable

public static class Reduce extends MapReduceBase

       implements Reducer<Text, Text, Text, IntWritable> {

       public void reduce(Text key, Iterator<Text> values,

                                   OutputCollector<Text, IntWritable> output,

                                   Reporter reporter) throws IOException {

              int count = 0;

              while (values.hasNext()) {

                     values.next();

                     count++;

              }

              output.collect(key, new IntWritable(count));

       }

}

 

计算不同引用次数专利的数目

之所以选择K2V2K3V3的数据为IntWritable类型,是因为它们的数据必然为整数,并且使用IntWritableText更高效

public class CitationHistogram extends Configured implements Tool {

       public static class MapClass extends MapReduceBase

              implements Mapper<Text, Text, IntWritable, IntWritable> {

              private final static IntWritable uno = new IntWritable(1);

              private IntWritable citationCount = new IntWritable();

              public void map(Text key, Text, value,

                                   OutputCollector<IntWritable, IntWritable> output,

                                   Reporter reporter) throws IOException {

                     citationCount.set(Integer.parseInt(value.toString()));

                     output.collect(citationCount, uno);

              }

       }

       public static class Reduce extends MapReduceBase

              implements Reducer<IntWritable, IntWritable, IntWritable, IntWritable> {

              public void reduce(IntWritable key, Iterator<IntWritable> values,

                                          OutputCollector<IntWritable, IntWritable > output,

                                          Reporter reporter) throws IOException {

                     int count = 0;

                     while (values.hasNext()) {

                            count += values.next().get();

                     }

                     output.collect(key, new IntWritable(count));

              }

       }

       public int run(String[] args) throws Exception {

              Configuration conf = getConf();

              JobConf job = new JobConf(conf, CitationHistogram.class);

              Path in = new Path(args[0]);

              Path out = new Path(args[1]);

              FileInputFormat.setInputPaths(job, in);

              FileOutputFormat.setOutputPath(job, out);

              job.setJobName("CitationHistogram");

              job.setMapperClass(MapClass.class);

              job.setReducerClass(Reduce.class);

              job.setInputFomrat(KeyValueTextInputFormat.class);

              job.setOutputFormat(TextOutputFormat.class);

              job.setOutputKeyClass(IntWritable.class);

              job.setOutputValueClass(IntWritable.class);

              JobClient.runJob(job);

              return 0;

       }

       public static void main(String[] args) throws Exception {

              int res = ToolRunner.run(new Configuration(), new CitationHistogram(), args);

              system.exit(res);

       }

}

需要说明的几点:

1、类名为CitationHistogram

2、输入格式为KeyValueTextInputFormat,输出格式为TextOutputFormat

3KeyValueTextInputFormat默认以"<tab>"制表符进行分割,可以使用job.set("key.value.separator.in.input.line", ","),修改分隔符为",",其他需要自行修改

4MapClass类使用了两个私有成员变量uno citationCount,为什么要这样定义呢?

出于对效率的考虑citationCountuno的定义被放在类中而不是方法中,有多少记录,map()方法就会被调用多少次 (对每个JVM而言,就是一个分片中的记录数)。减少在map()方法中生成的对象个数可以提高性能,并减少垃圾回收。由于citationCountuno被传递给output.collect(),我们依赖output.collect()方法的约定不会修改这两个对象。

5Reducer计算每个key对应的值的总数,这似乎并不高效,因为我们知道所有的值都是1,为什么我们还要去加它们呢?原因在于,它会让我们在以后能更容易地增加一个combiner来提高性能。

 

Hadoop API是改了又改,变了又变

10.20版本被视为旧API和未来稳定API之间的过渡

2、为了保持向后兼容,版本0.20以及之后的版本支持下一代API并将旧API标记为弃用

 

并不推荐马上转向新的API

10.20版本,许多Hadoop自身的类库还没有基于新的API重写,如果MapReduce代码使用0.20中的新API,这些类将无法被使用。

2、在0.20版本之前,0.18.3仍被很多人认为是最完备与最稳定的版本

3、虽然在新版本的API中有所改变,但是改变的仅仅影响基础的MapReduce模板,我们可以基于新API所做的改变,重写这个模板以备将来使用。

 

你可能会奇怪为什么不提0.19

一般的意见认为它的初始版本问题比较多,有许多bug,一些副版本试图解决这个问题,但社区希望直接跳到版本0.20

 

新版本的API做了哪些改动?

1、在新的APIorg.apahce.hadoop.mapred的许多类都被移走了,多数被放入org.apache.hadoop.mapreduce中,而且类库都放在org.apache.hadoop.mapreduce.lib的一个包里。当转为使用新API时,org.apache.hadoop.mapred下所有的类的import声明(或者完全引用)就不存在了,它们都被弃用

2、新API中最有益的变化是引入了上下文对象context,最直接的影响在于替换了map()reduce()方法中使用的OutputCollectorReporter对象。现在将通过调用Context.writer()而不是OutputCollector.collect()输出键/值对。深远的影响是统一了应用代码和MapReduce框架之间的通信,并固定了MapperReducerAPI,使得添加新功能时不会改变基本方法签名,新的功能仅仅时在context对象上增加的方法,在引入这些方法之前写的程序不会感知到这些新方法,它们可以在更新的版本中继续编译与运行

3、新的map()reduce()方法分别被包含在新的抽象MapperReducer中,它们取代了原始API中的MapperReducer接口(org.apache.hadoop.mapred.Mapperorg.apache.hadoop.mapred.Reducer)。新的抽象类也替换了MapReudceBase类,使之被弃用

4、新的map()reduce()方法多了一两处细微的改变,它们可以抛出InterruptedException而非单一的IOException,而且,reduce()方法不再以Iterator而以Iterable来接受一个值的列表,这样更容易使用Javaforeach语义来实现迭代。

 

回顾一下原始的API中的签名

public static class MapClass extends MapReduceBase

       implements Mapper<K1, V1, K2, V2> {

       public void map(K1 key, V1 value,

                                   OutputCollector<K2, V2> output,

                                   Reporter reporter) throws IOException { } 

}

public static class Reduce extends MapReduceBase

       implements Reducer<K2, V2, K3, V3> {

       public void reduce(K2 key, Iterator<V2> values,

                                   OutputCollector<K3, V3> output,

                                   Reporter reporter) throws IOException { }

}

 

新的API中的签名,体会与上面签名的不同

public static class MapClass extends Mapper<K1, V2, K2, V2> {

       public void map(K1 key, V1 value, Context context)

                                   throws IOException, InterruptedException { }

}

public static class Reduce extends Reducer<K2, V2, K3, V3> {

       public void reduce(K2 key, Iterable<V2> values, Context context)

                                   throws IOException, InterruptedException { }

}


你还需要改变driver中的一些内容来支持新的API

1、在新的APIJobConfJobClient被替换了,它们的功能已经被放入Configuration(它原本是JobConf的父类)和一个新的类Job

2Configuration类纯粹为了配置作业而设,而Job类负责定义和控制一个作业的执行

3、比如,setOutputKeyClass()setOutputValueClass()等方法被从JobConf转移到了Job

4、作业的构造和提交执行现在放在Job中,原本需要使用JobConf来构造一个作业:

JobConf job = new JobConf(conf, MyJob.class);

job.setJobName("MyJob");

而现在可通过Job类完成:

Job job = new Job(conf, "MyJob");

job.setJarByClass(MyJob.class);

以前是通过JobClient提交作业去执行:

JobClient.runJob(job);

现在同样通过Job类来完成

System.exit(job.waitForCompletion(true) ? 0 : 1);

 

基于版本0.20及其以上的新API重写的Hadoop基础程序模板(Hadoop 1.X也适用)

public class MyJob extends Configured implements Tool {

       public static class MapClass extends Mapper<LongWritable, Text, Text, Text> {

              public void map(LongWirtable key, Text value, Context context)

                                          throws IOException, InterruptedException {

                     String[] citation = value.toString().split(",");

                     context.write(new Text(citation[1]), new Text(citation[0]));

              }

       }

       public static class Reduce extends Reducer<Text, Text, Text, Text> {

              // Iterable类型允许foreach循环

              public void reduce(Text key, Iterable<Text> values, Context context)

                                          throws IOException, InterruptedException {

                     for (Text val : values) {

                            if (csv.length() > 0) csv += ",";

                            csv += val.toString();

                     }

                     context.write(key, new Text(csv));

              }

       }

       public int run(String[] args) throws Exception {

              Configuration conf = getConf();

              Job job = new Job(conf, "MyJob");

              job.setJarByClass(MyJob.class);

              Path in = new Path(args[0]);

              Path out = new Path(args[1]);

              FileInputFormat.setInputPaths(job, in);

              FileOutputFormat.setOutputPath(job, out);

              job.setMapperClass(MapClass.class);

              job.setReducerClass(Reduce,.class);

              // 兼容InputFormat

              job.setInputFormatClass(TextInputFormat.class);

              job.setOutputFormatClass(TextOutputFormat.class);

              job.setOutputKeyClass(Text.class);

              job.setOutputValueClass(Text.class);

              System.exit(job.waitForCompletion(true)?0:1);

              return 0;

       }

       public static void main(String[] args) throws Exception {

              int res = ToolRunner.run(new Configuration(), new MyJob(), args);

              System.exit(res);

       }

}

1、这段代码实现了反向索引功能

2KeyValueTextInputFormat类未被移植到版本0.20的新API中,重写这个模板我们不得不使用TextInputFormat


© 著作权归作者所有

共有 人打赏支持
祥林会跟你远走高飞
粉丝 26
博文 49
码字总数 98029
作品 0
昌平
程序员
读书笔记_Index

第1章 Java性能调优概述 第2章 设计优化 第3章 Java程序优化 第4章 并行程序开发及优化 第5章 JVM调优 第6章 Java性能调优工具 第1章 简介 第2章 线程安全性 第3章 对象的共享 第1章 走近Jav...

陶邦仁 ⋅ 2014/03/19 ⋅ 0

Hadoop实战读书笔记(5)

HDFS文件操作 你可以把一个大数据集(100TB)在HDFS中存储为单个文件,而大多数其他的文件系统无力实现这一点。虽然该文件存在多个副本分布在多台机器上来支持并行处理,你也不必考虑这些细节...

祥林会跟你远走高飞 ⋅ 2014/12/08 ⋅ 0

JavaScript、jQuery、HTML5、Node.js实例大全-读书笔记3

技术很多,例子很多,只好慢慢学,慢慢实践!!现在学的这本书是【JavaScript实战----JavaScript、jQuery、HTML5、Node.js实例大全】 JavaScript、jQuery、HTML5、Node.js实例大全-读书笔记2...

woIwoI ⋅ 2014/10/30 ⋅ 0

优秀技术网址收集

Ruthless java多线程,java高级特性,Android基础,Android高级,Android常用控件,j2ee案例,Redis,Spring,javascript,Linux,Oracle,Ext,Hadoop,Jquery,Lucence,Nginx,Dubbo等 孤狼...

HenrySun ⋅ 2015/07/28 ⋅ 0

Hadoop实战读书笔记(7)

输入数据概要 输入数据通常驻留在较大的文件中,通常几十或者数百GB,甚至更大。MapReduce处理的基本原则之一是将输入数据分割成块。这些块可以在多台计算机上并行处理,在Hadoop的术语中这些...

祥林会跟你远走高飞 ⋅ 2014/12/08 ⋅ 0

Hadoop实战读书笔记(6)

putmerge程序的大体流程是? 1、根据用户定义的参数设置本地目录和HDFS的目录文件 2、提取本地输入目录中每个文件的信息 3、创建一个输出流写入到HDF文件 4、遍历本地目录中的每个文件,打开...

祥林会跟你远走高飞 ⋅ 2014/12/08 ⋅ 0

敏捷教练成长记:漫漫长路第三周

看到跆拳道的软文,讲到: 学跆拳道的正确顺序: 第一阶段:有兴趣 第二阶段:没兴趣 第三阶段:逼练习 第四阶段:成习惯 第五阶段:有兴趣 第六阶段:真热爱 大部分家长在孩子第二阶段时放弃...

转型实践者 ⋅ 2017/11/17 ⋅ 0

2017年年终总结

前言 不知不觉,2017年又接近尾声了,又到了该写年终总结的时候了,往年这个时候都会熙熙攘攘,各大平台提早预热过年的气氛,而今年显得格外的平静,这可能正如我的现在的心境,波澜而不惊!...

韩俊强 ⋅ 01/03 ⋅ 0

Hadoop实战读书笔记(8)

什么是开发数据集? 一个流行的开发策略是为生产环境中的大数据集建立一个较小的、抽样的数据子集,称为开发数据集。这个开发数据集可能只有几百兆字节。当你以单机或者伪分布式模式编写程序...

祥林会跟你远走高飞 ⋅ 2014/12/08 ⋅ 0

敏捷教练成长记:秋高气爽第四周

不知不觉坚持了四周了,这周很忙,写读书笔记时尽显疲态,有厌倦的感觉了。需要自我调整,继续坚持。 1、敏捷方面读不少于50页的书或者文章。 阅读《持续交付-发布可靠软件的系统方法》第三章...

转型实践者 ⋅ 2017/11/26 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

十五周二次课

十五周二次课 17.1mysql主从介绍 17.2准备工作 17.3配置主 17.4配置从 17.5测试主从同步 17.1mysql主从介绍 MySQL主从介绍 MySQL主从又叫做Replication、AB复制。简单讲就是A和B两台机器做主...

河图再现 ⋅ 今天 ⋅ 0

docker安装snmp rrdtool环境

以Ubuntu16:04作为基础版本 docker pull ubuntu:16.04 启动一个容器 docker run -d -i -t --name flow_mete ubuntu:16.04 bash 进入容器 docker exec -it flow_mete bash cd ~ 安装基本软件 ......

messud4312 ⋅ 今天 ⋅ 0

OSChina 周一乱弹 —— 快别开心了,你还没有女友呢。

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子 :分享吴彤的单曲《好春光》 《好春光》- 吴彤 手机党少年们想听歌,请使劲儿戳(这里) @clouddyy :小萝莉街上乱跑,误把我认错成...

小小编辑 ⋅ 今天 ⋅ 7

mysql in action / alter table

change character set ALTER SCHEMA `employees` DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci ;ALTER TABLE `employees`.`t2` CHARACTER SET = utf8mb4 , COLLAT......

qwfys ⋅ 今天 ⋅ 0

Java 开发者不容错过的 12 种高效工具

Java 开发者常常都会想办法如何更快地编写 Java 代码,让编程变得更加轻松。目前,市面上涌现出越来越多的高效编程工具。所以,以下总结了一系列工具列表,其中包含了大多数开发人员已经使用...

jason_kiss ⋅ 昨天 ⋅ 0

Linux下php访问远程ms sqlserver

1、安装freetds(略,安装在/opt/local/freetds 下) 2、cd /path/to/php-5.6.36/ 进入PHP源码目录 3、cd ext/mssql进入MSSQL模块源码目录 4、/opt/php/bin/phpize生成编译配置文件 5、 . ./...

wangxuwei ⋅ 昨天 ⋅ 0

如何成为技术专家

文章来源于 -- 时间的朋友 拥有良好的心态。首先要有空杯心态,用欣赏的眼光发现并学习别人的长处,包括但不限于工具的使用,工作方法,解决问题以及规划未来的能力等。向别人学习的同时要注...

长安一梦 ⋅ 昨天 ⋅ 0

Linux vmstat命令实战详解

vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况。这个命令是我查看Linux/Unix最喜爱的命令...

刘祖鹏 ⋅ 昨天 ⋅ 0

MySQL

查看表相关命令 - 查看表结构    desc 表名- 查看生成表的SQL    show create table 表名- 查看索引    show index from  表名 使用索引和不使用索引 由于索引是专门用于加...

stars永恒 ⋅ 昨天 ⋅ 0

easyui学习笔记

EasyUI常用控件禁用方法 combobox $("#id").combobox({ disabled: true }); ----- $("#id").combobox({ disabled: false}); validatebox $("#id").attr("readonly", true); ----- $("#id").r......

miaojiangmin ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部