Eclipse
Ubuntu14.0.1
Hadoop2.0.6
hadoop-eclipse-plugin-2.6.0.jar
Ssh安全外壳协议
Openjdk1.7
Linux(32位)+jdk \hadoop伪分布式
1.对《Hadoop实战中文版》第一章进行学习,对hadoop的历史及其起源有了大概的了解,并对MapReduce有一定的了解。MapReduce主要有俩个阶段,分别是mapping和reducing,相应的每个阶段都有一个非常重要的函数,那就是mapper和reducer,我的理解是mapper是接收传入的输入文件,并将其信息传给reducer,之后,reducer通过mapper传过来的数据进行处理并返回最终结果。
1.运行hadoop内部实例单词计数WordCount,其过程如下:
(1)切换到hadoop的安装路径下
cd /usr/local/hadoop
(2)创建运行实例需要用到的输入文件存放的文件夹,接着 将 etc/hadoop 中的文件作为输入文件复制到分布式文件系统中,即将 /usr/local/hadoop/etc/hadoop 复制到分布式文件系统中的 /user/hadoop/input 中.
bin/hdfs dfs -mkdir input
bin/hdfs dfs -put etc/hadoop/*.xml input
(3)调用执行wordcount
bin/hadoop jar share/hadoop/mapreduce/
hadoop-mapreduce-examples-2.6.0.jar wordcount input output
(4)查看执行结果(执行完之后需删除output,该文件夹是生成的)
bin/hdfs dfs -cat output/*
bin/hdfs dfs -rm -r /user/hadoop/output # 删除 output 文件夹
1. 特殊数据类型介绍
Hadoop提供了如下内容的数据类型,这些数据类型都实现了WritableComparable接口,以便用这些类型定义的数据可以被序列化进行网络传输和文件存储,以及进行大小比较。
BooleanWritable:标准布尔型数值
ByteWritable:单字节数值
DoubleWritable:双字节数
FloatWritable:浮点数
IntWritable:整型数
LongWritable:长整型数
Text:使用UTF8格式存储的文本
NullWritable:当
2. 主方法main分析
public static void main(String[] args) throws Exception {
JobConf conf = new JobConf(WordCount.class);
conf.setJobName("wordcount");
conf.setOutputKeyClass(Text.class);
conf.setOutputValueClass(IntWritable.class);
conf.setMapperClass(Map.class);
conf.setCombinerClass(Reduce.class);
conf.setReducerClass(Reduce.class);
conf.setInputFormat(TextInputFormat.class);
conf.setOutputFormat(TextOutputFormat.class);
FileInputFormat.setInputPaths(conf, new Path(args[0]));
FileOutputFormat.setOutputPath(conf, new Path(args[1]));
JobClient.runJob(conf);
}
首先讲解一下Job的初始化过程。main函数调用Jobconf类来对MapReduce Job进行初始化,然后调用setJobName()方法命名这个Job。对Job进行合理的命名有助于更快地找到Job,以便在JobTracker和Tasktracker的页面中对其进行监视。
JobConf conf = new JobConf(WordCount. class ); conf.setJobName("wordcount" );
接着设置Job输出结果
conf.setOutputKeyClass(Text.class );
conf.setOutputValueClass(IntWritable.class );
然后设置Job处理的Map(拆分)、Combiner(中间结果合并)以及Reduce(合并)的相关处理类。这里用Reduce类来进行Map产生的中间结果合并,避免给网络数据传输产生压力。
conf.setMapperClass(Map.class );
conf.setCombinerClass(Reduce.class );
conf.setReducerClass(Reduce.class );
接着就是调用setInputPath()和setOutputPath()设置输入输出路径。
conf.setInputFormat(TextInputFormat.class );
conf.setOutputFormat(TextOutputFormat.class );
(1)InputFormat和InputSplit
InputSplit是Hadoop定义的用来传送给每个单独的map的数据,InputSplit存储的并非数据本身,而是一个分片长度和一个记录数据位置的数组。生成InputSplit的方法可以通过InputFormat()来设置。
当数据传送给map时,map会将输入分片传送到InputFormat,InputFormat则调用方法getRecordReader()生成RecordReader,RecordReader再通过creatKey()、creatValue()方法创建可供map处理的
Hadoop预定义了多种方法将不同类型的输入数据转化为map能够处理的
InputFormat
|
|---BaileyBorweinPlouffe.BbpInputFormat
|---ComposableInputFormat
|---CompositeInputFormat
|---DBInputFormat
|---DistSum.Machine.AbstractInputFormat
|---FileInputFormat
|---CombineFileInputFormat
|---KeyValueTextInputFormat
|---NLineInputFormat
|---SequenceFileInputFormat
|---TeraInputFormat
|---TextInputFormat
其中TextInputFormat是Hadoop默认的输入方法,在TextInputFormat中,每个文件(或其一部分)都会单独地作为map的输入,而这个是继承自FileInputFormat的。之后,每行数据都会生成一条记录,每条记录则表示成
key值是每个数据的记录在数据分片中字节偏移量,数据类型是LongWritable;
value值是每行的内容,数据类型是Text。
(2)OutputFormat
每一种输入格式都有一种输出格式与其对应。默认的输出格式是TextOutputFormat,这种输出方式与输入类似,会将每条记录以一行的形式存入文本文件。不过,它的键和值可以是任意形式的,因为程序内容会调用toString()方法将键和值转换为String类型再输出。
3 Map类中的map方法分析
public static class Map extends MapReduceBase implements
Mapper
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
public void map(LongWritable key, Text value,
OutputCollector
throws IOException {
String line = value.toString();
StringTokenizer tokenizer = new StringTokenizer(line);
while (tokenizer.hasMoreTokens()) {
word.set(tokenizer.nextToken());
output.collect(word, one);
}
}
}
Map类继承自MapReduceBase,并且它实现了Mapper接口,此接口是一个规范类型,它有4种形式的参数,分别用来指定map的输入key值类型、输入value值类型、输出key值类型和输出value值类型。在本例中,因为使用的是TextInputFormat,它的输出key值是LongWritable类型,输出value值是Text类型,所以map的输入类型为
实现此接口类还需要实现map方法,map方法会具体负责对输入进行操作,在本例中,map方法对输入的行以空格为单位进行切分,然后使用OutputCollect收集输出的
4 Reduce类中reduce方法分析
public static class Reduce extends MapReduceBase implements
Reducer
public void reduce(Text key, Iterator
OutputCollector
throws IOException {
int sum = 0;
while (values.hasNext()) {
sum += values.next().get();
}
output.collect(key, new IntWritable(sum));
}
}
Reduce类也是继承自MapReduceBase的,需要实现Reducer接口。Reduce类以map的输出作为输入,因此Reduce的输入类型是
(wordCount分析学习摘自:
http://www.cnblogs.com/xia520pi/archive/2012/05/16/2504205.html)
通过学习《Hadoop实战》,对wordCount的原理,整个代码以及hadoop是怎么获取数据处理数据有了模糊的了解,按书上的进度,今天也改写了wordCount,在分析处理数据的时候,忽略大小写,筛选文件中出现的次数多余四次的单词,但是,自身对其理解还是不够。今天最大的收获是能在eclipse中编写代码,在编译成jar包,放入hadoop服务器,并运行。对MapReduce也有了进一步理解,它分为两个阶段,分别是mapping和reducing,同时这两个阶段有两个很重要的函数,就是mapper和reducer,mapper是负责接收数据并做初步处理,而reducer是对mapper传过来的数据做进一步的处理,例如在WordCount中,reducer就是累加相同的单词,最后返回最终结果。
(1)第一次执行jar包的时候,没有删除输出文件夹,报错。在今天的例子中,输出结果文件夹output是每次执行的时候自动生成,所有在使用完之后,需要删除。