Hadoop日记Day17---计数器、map规约、分区学习
一、Hadoop计数器
1.1 什么是Hadoop计数器
Haoop是处理大数据的,不适合处理小数据,有些大数据问题是小数据程序是处理不了的,他是一个高延迟的任务,有时处理一个大数据需要花费好几个小时这都是正常的。下面我们说一下Hadoop计数器,Hadoop计数器就相当于我们的日志,而日志可以让我们查看程序运行时的很多状态,而计数器也有这方面的作用。那么就研究一下Hadoop自身的计数器。计数器的程序如代码1.1所示,下面代码还是以内容为“hello you;hell0 me”的单词统计为例。
package counter; import java.net.URI; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Counter;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.mapreduce.lib.partition.HashPartitioner; public class WordCountApp {
static final String INPUT_PATH = "hdfs://hadoop:9000/input";
static final String OUT_PATH = "hdfs://hadoop:9000/output"; public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); final FileSystem fileSystem = FileSystem.get(new URI(INPUT_PATH), conf);
final Path outPath = new Path(OUT_PATH); if(fileSystem.exists(outPath)){
fileSystem.delete(outPath, true);
}
final Job job = new Job(conf , WordCountApp.class.getSimpleName()); //1.1指定读取的文件位于哪里
FileInputFormat.setInputPaths(job, INPUT_PATH);
job.setInputFormatClass(TextInputFormat.class);//指定如何对输入文件进行格式化,把输入文件每一行解析成键值对 //1.2 指定自定义的map类
job.setMapperClass(MyMapper.class);
job.setMapOutputKeyClass(Text.class);//map输出的<k,v>类型。
job.setMapOutputValueClass(LongWritable.class);//如果<k3,v3>的类型与<k2,v2>类型一致,则可以省略 //1.3 分区
job.setPartitionerClass(HashPartitioner.class);
job.setNumReduceTasks(1);//有一个reduce任务运行 //2.2 指定自定义reduce类
job.setReducerClass(MyReducer.class); job.setOutputKeyClass(Text.class);//指定reduce的输出类型
job.setOutputValueClass(LongWritable.class); //2.3 指定写出到哪里
FileOutputFormat.setOutputPath(job, outPath);
job.setOutputFormatClass(TextOutputFormat.class);//指定输出文件的格式化类 job.waitForCompletion(true);//把job提交给JobTracker运行
} /**
* KEYIN 即k1 表示行的偏移量
* VALUEIN 即v1 表示行文本内容
* KEYOUT 即k2 表示行中出现的单词
* VALUEOUT 即v2 表示行中出现的单词的次数,固定值1
*/
static class MyMapper extends Mapper<LongWritable, Text, Text, LongWritable>{
protected void map(LongWritable k1, Text v1, Context context) throws java.io.IOException ,InterruptedException {
final String line = v1.toString();
final String[] splited = line.split("\t");
for (String word : splited) {
context.write(new Text(word), new LongWritable(1));
}
};
} /**
* KEYIN 即k2 表示行中出现的单词
* VALUEIN 即v2 表示行中出现的单词的次数
* KEYOUT 即k3 表示文本中出现的不同单词
* VALUEOUT 即v3 表示文本中出现的不同单词的总次数
*
*/
static class MyReducer extends Reducer<Text, LongWritable, Text, LongWritable>{
protected void reduce(Text k2, java.lang.Iterable<LongWritable> v2s, Context ctx) throws java.io.IOException ,InterruptedException {
long times = 0L;
for (LongWritable count : v2s) {
times += count.get();
}
ctx.write(k2, new LongWritable(times));
};
} }
代码 1.1
运行结果如下图1.1所示。
Counters: 19//Counter表示计数器,19表示有19个计数器(下面一共4计数器组)
File Output Format Counters //文件输出格式化计数器组
Bytes Written=19 //reduce输出到hdfs的字节数,一共19个字节
FileSystemCounters//文件系统计数器组
FILE_BYTES_READ=481
HDFS_BYTES_READ=38
FILE_BYTES_WRITTEN=81316
HDFS_BYTES_WRITTEN=19
File Input Format Counters //文件输入格式化计数器组
Bytes Read=19 //map从hdfs读取的字节数
Map-Reduce Framework//MapReduce框架
Map output materialized bytes=49
Map input records=2 //map读入的记录行数,读取两行记录,”hello you”,”hello me”
Reduce shuffle bytes=0//规约分区的字节数
Spilled Records=8
Map output bytes=35
Total committed heap usage (bytes)=266469376
SPLIT_RAW_BYTES=105
Combine input records=0//合并输入的记录数
Reduce input records=4 //reduce从map端接收的记录行数
Reduce input groups=3 //reduce函数接收的key数量,即归并后的k2数量
Combine output records=0//合并输出的记录数
Reduce output records=3 //reduce输出的记录行数。<helllo,{1,1}>,<you,{1}>,<me,{1}>
Map output records=4 //map输出的记录行数,输出4行记录
图 1.1
通过上面我们对计数器的分析,可以知道,我们可以通过计数器来分析MapReduece程序的运行状态。
1.2 自定义计数器
通过上面的分析,我们了解了计数器的作用,那么我们可以自定义一个计数器,来实现我们自己想要的功能。如定义一个记录敏感词的计数器,记录敏感词在一行所出现的次数,如代码2.1所示。我们处理文件内容为“hello you”,“hello me”。
Counters: 19//Counter表示计数器,19表示有19个计数器(下面一共4计数器组)
File Output Format Counters //文件输出格式化计数器组
Bytes Written=19 //reduce输出到hdfs的字节数,一共19个字节
FileSystemCounters//文件系统计数器组
FILE_BYTES_READ=481
HDFS_BYTES_READ=38
FILE_BYTES_WRITTEN=81316
HDFS_BYTES_WRITTEN=19
File Input Format Counters //文件输入格式化计数器组
Bytes Read=19 //map从hdfs读取的字节数
Map-Reduce Framework//MapReduce框架
Map output materialized bytes=49
Map input records=2 //map读入的记录行数,读取两行记录,”hello you”,”hello me”
Reduce shuffle bytes=0//规约分区的字节数
Spilled Records=8
Map output bytes=35
Total committed heap usage (bytes)=266469376
SPLIT_RAW_BYTES=105
Combine input records=0//合并输入的记录数
Reduce input records=4 //reduce从map端接收的记录行数
Reduce input groups=3 //reduce函数接收的key数量,即归并后的k2数量
Combine output records=0//合并输出的记录数
Reduce output records=3 //reduce输出的记录行数。<helllo,{1,1}>,<you,{1}>,<me,{1}>
Map output records=4 //map输出的记录行数,输出4行记录
代码2.1
运行结果如下图2.1所示。
Counters: 20
Sensitive Words
hello=2
File Output Format Counters
Bytes Written=21
FileSystemCounters
FILE_BYTES_READ=359
HDFS_BYTES_READ=42
FILE_BYTES_WRITTEN=129080
HDFS_BYTES_WRITTEN=21
File Input Format Counters
Bytes Read=21
Map-Reduce Framework
Map output materialized bytes=67
Map input records=2
Reduce shuffle bytes=0
Spilled Records=8
Map output bytes=53
Total committed heap usage (bytes)=391774208
SPLIT_RAW_BYTES=95
Combine input records=0
Reduce input records=4
Reduce input groups=3
Combine output records=0
Reduce output records=3
Map output records=4
图 2.1
二、Combiners编程
2.1 什么是Combiners
从上面程序运行的结果我们可以发现,在Map-Reduce Framework即MapReduce框架的输出中,Combine input records这个字段为零, 那么combine怎么使用呢?其实这是MapReduce程序中Mapper任务中第五步,这是可选的一步,使用方法非常简单,以上面单词统计为例,只需添加下面一行代码即可,如下: job.setCombinerClass(MyReducer.class);
combine操作是一个可选的操作,使用时需要我们自己设定,我们用MyReducer类来设置Combiners,表示Combiners与Reduce功能相同,带有combine功能的MapRduce程序如代码3.1所示。
package combine; import java.net.URI; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Partitioner;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.jasper.tagplugins.jstl.core.If; public class WordCountApp2 {
static final String INPUT_PATH = "hdfs://hadoop:9000/hello";
static final String OUT_PATH = "hdfs://hadoop:9000/out"; public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
final FileSystem fileSystem = FileSystem.get(new URI(INPUT_PATH), conf);
final Path outPath = new Path(OUT_PATH);
if(fileSystem.exists(outPath)){
fileSystem.delete(outPath, true);
}
final Job job = new Job(conf , WordCountApp2.class.getSimpleName());
job.setJarByClass(WordCountApp2.class); //1.1指定读取的文件位于哪里
FileInputFormat.setInputPaths(job, INPUT_PATH);
job.setInputFormatClass(TextInputFormat.class);//指定如何对输入文件进行格式化,把输入文件每一行解析成键值对 //1.2 指定自定义的map类
job.setMapperClass(MyMapper.class);
job.setMapOutputKeyClass(Text.class);//map输出的<k,v>类型。
job.setMapOutputValueClass(LongWritable.class);//如果<k3,v3>的类型与<k2,v2>类型一致,则可以省略 //1.3 分区
job.setPartitionerClass(MyPartitioner.class);
//有几个reduce任务运行
job.setNumReduceTasks(2); //1.4 TODO 排序、分组 //1.5 规约
job.setCombinerClass(MyCombiner.class); //2.2 指定自定义reduce类
job.setReducerClass(MyReducer.class);
//指定reduce的输出类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class); //2.3 指定写出到哪里
FileOutputFormat.setOutputPath(job, outPath);
//指定输出文件的格式化类
//job.setOutputFormatClass(TextOutputFormat.class); //把job提交给JobTracker运行
job.waitForCompletion(true);
} static class MyPartitioner extends Partitioner<Text, LongWritable>{
@Override
public int getPartition(Text key, LongWritable value, int numReduceTasks) {
return (key.toString().equals("hello"))?0:1;
}
} /**
* KEYIN 即k1 表示行的偏移量
* VALUEIN 即v1 表示行文本内容
* KEYOUT 即k2 表示行中出现的单词
* VALUEOUT 即v2 表示行中出现的单词的次数,固定值1
*/
static class MyMapper extends Mapper<LongWritable, Text, Text, LongWritable>{
protected void map(LongWritable k1, Text v1, Context context) throws java.io.IOException ,InterruptedException {
final String[] splited = v1.toString().split("\t");
for (String word : splited) {
context.write(new Text(word), new LongWritable(1));
System.out.println("Mapper输出<"+word+","+1+">");
}
};
} /**
* KEYIN 即k2 表示行中出现的单词
* VALUEIN 即v2 表示行中出现的单词的次数
* KEYOUT 即k3 表示文本中出现的不同单词
* VALUEOUT 即v3 表示文本中出现的不同单词的总次数
*
*/
static class MyReducer extends Reducer<Text, LongWritable, Text, LongWritable>{
protected void reduce(Text k2, java.lang.Iterable<LongWritable> v2s, Context ctx) throws java.io.IOException ,InterruptedException {
//显示次数表示redcue函数被调用了多少次,表示k2有多少个分组
System.out.println("MyReducer输入分组<"+k2.toString()+",...>");
long times = 0L;
for (LongWritable count : v2s) {
times += count.get();
//显示次数表示输入的k2,v2的键值对数量
System.out.println("MyReducer输入键值对<"+k2.toString()+","+count.get()+">");
}
ctx.write(k2, new LongWritable(times));
};
} static class MyCombiner extends Reducer<Text, LongWritable, Text, LongWritable>{
protected void reduce(Text k2, java.lang.Iterable<LongWritable> v2s, Context ctx) throws java.io.IOException ,InterruptedException {
//显示次数表示redcue函数被调用了多少次,表示k2有多少个分组
System.out.println("Combiner输入分组<"+k2.toString()+",...>");
long times = 0L;
for (LongWritable count : v2s) {
times += count.get();
//显示次数表示输入的k2,v2的键值对数量
System.out.println("Combiner输入键值对<"+k2.toString()+","+count.get()+">");
} ctx.write(k2, new LongWritable(times));
//显示次数表示输出的k2,v2的键值对数量
System.out.println("Combiner输出键值对<"+k2.toString()+","+times+">");
};
}
}
代码 3.1
运行结果如下图3.1所示。
Counters: 20
Sensitive Words
hello=2
File Output Format Counters
Bytes Written=21
FileSystemCounters
FILE_BYTES_READ=359
HDFS_BYTES_READ=42
FILE_BYTES_WRITTEN=129080
HDFS_BYTES_WRITTEN=21
File Input Format Counters
Bytes Read=21
Map-Reduce Framework
Map output materialized bytes=67
Map input records=2
Reduce shuffle bytes=0
Spilled Records=8
Map output bytes=53
Total committed heap usage (bytes)=391774208
SPLIT_RAW_BYTES=95
Combine input records=
Reduce input records=
Reduce input groups=3
Combine output records=
Reduce output records=3
Map output records=4
图 3.1
从上面的运行结果我们可以发现,此时Combine input records=4,Combine output records=3,Reduce input records=3,因为Combine阶段在Ma pper结束与Reducer开始之间,Combiners处理的数据,就是在不设置Combiners时,Reduce所应该接受的数据,所以为4,然后再将Combiners的输出作为Re duce端的输入,所以Reduce input records这个字段由4变成了3。注意,combine操作是一个可选的操作,使用时需要我们自己设定,在本代码中我们用MyRed ucer类来设置Combiners,Combine方法的使用的是Reduce的方法,这说明归约的方法是通用的,Reducer阶段的方法也可以用到Mapper阶段。
2.1 自定义Combiners
为了能够更加清晰的理解Combiners的工作原理,我们自定义一个Combiners类,不再使用MyReduce做为Combiners的类,如代码3.2所示。
package combine; import java.net.URI; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Partitioner;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.jasper.tagplugins.jstl.core.If; /**
* 问:为什么使用Combiner?
* 答:Combiner发生在Map端,对数据进行规约处理,数据量变小了,传送到reduce端的数据量变小了,传输时间变短,作业的整体时间变短。
*
* 问:为什么Combiner不作为MR运行的标配,而是可选步骤哪?
* 答:因为不是所有的算法都适合使用Combiner处理,例如求平均数。
*
* 问:Combiner本身已经执行了reduce操作,为什么在Reducer阶段还要执行reduce操作哪?
* 答:combiner操作发生在map端的,处理一个任务所接收的文件中的数据,不能跨map任务执行;只有reduce可以接收多个map任务处理的数据。
*
*/
public class WordCountApp2 {
static final String INPUT_PATH = "hdfs://hadoop:9000/hello";
static final String OUT_PATH = "hdfs://hadoop:9000/out"; public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
final FileSystem fileSystem = FileSystem.get(new URI(INPUT_PATH), conf);
final Path outPath = new Path(OUT_PATH);
if(fileSystem.exists(outPath)){
fileSystem.delete(outPath, true);
}
final Job job = new Job(conf , WordCountApp2.class.getSimpleName());
job.setJarByClass(WordCountApp2.class); //1.1指定读取的文件位于哪里
FileInputFormat.setInputPaths(job, INPUT_PATH);
job.setInputFormatClass(TextInputFormat.class);//指定如何对输入文件进行格式化,把输入文件每一行解析成键值对 //1.2 指定自定义的map类
job.setMapperClass(MyMapper.class);
job.setMapOutputKeyClass(Text.class);//map输出的<k,v>类型。
job.setMapOutputValueClass(LongWritable.class);//如果<k3,v3>的类型与<k2,v2>类型一致,则可以省略 //1.3 分区
job.setPartitionerClass(MyPartitioner.class);
//有几个reduce任务运行
job.setNumReduceTasks(2); //1.4 TODO 排序、分组 //1.5 规约
job.setCombinerClass(MyCombiner.class); //2.2 指定自定义reduce类
job.setReducerClass(MyReducer.class);
//指定reduce的输出类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class); //2.3 指定写出到哪里
FileOutputFormat.setOutputPath(job, outPath);
//指定输出文件的格式化类
//job.setOutputFormatClass(TextOutputFormat.class); //把job提交给JobTracker运行
job.waitForCompletion(true);
} static class MyPartitioner extends Partitioner<Text, LongWritable>{
@Override
public int getPartition(Text key, LongWritable value, int numReduceTasks) {
return (key.toString().equals("hello"))?0:1;
}
} /**
* KEYIN 即k1 表示行的偏移量
* VALUEIN 即v1 表示行文本内容
* KEYOUT 即k2 表示行中出现的单词
* VALUEOUT 即v2 表示行中出现的单词的次数,固定值1
*/
static class MyMapper extends Mapper<LongWritable, Text, Text, LongWritable>{
protected void map(LongWritable k1, Text v1, Context context) throws java.io.IOException ,InterruptedException {
final String[] splited = v1.toString().split("\t");
for (String word : splited) {
context.write(new Text(word), new LongWritable(1));
System.out.println("Mapper输出<"+word+","+1+">");
}
};
} /**
* KEYIN 即k2 表示行中出现的单词
* VALUEIN 即v2 表示行中出现的单词的次数
* KEYOUT 即k3 表示文本中出现的不同单词
* VALUEOUT 即v3 表示文本中出现的不同单词的总次数
*
*/
static class MyReducer extends Reducer<Text, LongWritable, Text, LongWritable>{
protected void reduce(Text k2, java.lang.Iterable<LongWritable> v2s, Context ctx) throws java.io.IOException ,InterruptedException {
//显示次数表示redcue函数被调用了多少次,表示k2有多少个分组
System.out.println("MyReducer输入分组<"+k2.toString()+",...>");
long times = 0L;
for (LongWritable count : v2s) {
times += count.get();
//显示次数表示输入的k2,v2的键值对数量
System.out.println("MyReducer输入键值对<"+k2.toString()+","+count.get()+">");
}
ctx.write(k2, new LongWritable(times));
};
} static class MyCombiner extends Reducer<Text, LongWritable, Text, LongWritable>{
protected void reduce(Text k2, java.lang.Iterable<LongWritable> v2s, Context ctx) throws java.io.IOException ,InterruptedException {
//显示次数表示redcue函数被调用了多少次,表示k2有多少个分组
System.out.println("Combiner输入分组<"+k2.toString()+",...>");
long times = 0L;
for (LongWritable count : v2s) {
times += count.get();
//显示次数表示输入的k2,v2的键值对数量
System.out.println("Combiner输入键值对<"+k2.toString()+","+count.get()+">");
} ctx.write(k2, new LongWritable(times));
//显示次数表示输出的k2,v2的键值对数量
System.out.println("Combiner输出键值对<"+k2.toString()+","+times+">");
};
}
}
代码 3.2
运行结果如图3.2所示。
14/10/07 18:56:32 INFO mapred.MapTask: record buffer = 262144/327680
Mapper输出<hello,1>
14/10/07 18:56:32 INFO mapred.MapTask: Starting flush of map output
Mapper输出<world,1>
Mapper输出<hello,1>
Mapper输出<me,1>
Combiner输入分组<hello,...>
Combiner输入键值对<hello,1>
Combiner输入键值对<hello,1>
Combiner输出键值对<hello,2>
Combiner输入分组<me,...>
Combiner输入键值对<me,1>
Combiner输出键值对<me,1>
Combiner输入分组<world,...>
Combiner输入键值对<world,1>
Combiner输出键值对<world,1>
14/10/07 18:56:32 INFO mapred.MapTask: Finished spill 0
14/10/07 18:56:32 INFO mapred.Task: Task:attempt_local_0001_m_000000_0 is done. And is in the process of commiting
14/10/07 18:56:32 INFO mapred.LocalJobRunner:
14/10/07 18:56:32 INFO mapred.Task: Task 'attempt_local_0001_m_000000_0' done.
14/10/07 18:56:32 INFO mapred.Task: Using ResourceCalculatorPlugin : null
14/10/07 18:56:32 INFO mapred.LocalJobRunner:
14/10/07 18:56:32 INFO mapred.Merger: Merging 1 sorted segments
14/10/07 18:56:32 INFO mapred.Merger: Down to the last merge-pass, with 1 segments left of total size: 47 bytes
14/10/07 18:56:32 INFO mapred.LocalJobRunner:
MyReducer输入分组<hello,...>
MyReducer输入键值对<hello,2>
MyReducer输入分组<me,...>
MyReducer输入键值对<me,1>
MyReducer输入分组<world,...>
MyReducer输入键值对<world,1>
14/10/07 18:56:33 INFO mapred.Task: Task:attempt_local_0001_r_000000_0 is done. And is in the process of commiting
14/10/07 18:56:33 INFO mapred.LocalJobRunner:
14/10/07 18:56:33 INFO mapred.Task: Task attempt_local_0001_r_000000_0 is allowed to commit now
14/10/07 18:56:33 INFO output.FileOutputCommitter: Saved output of task 'attempt_local_0001_r_000000_0' to hdfs://hadoop:9000/output
14/10/07 18:56:33 INFO mapred.LocalJobRunner: reduce > reduce
14/10/07 18:56:33 INFO mapred.Task: Task 'attempt_local_0001_r_000000_0' done.
14/10/07 18:56:33 INFO mapred.JobClient: map 100% reduce 100%
14/10/07 18:56:33 INFO mapred.JobClient: Job complete: job_local_0001
14/10/07 18:56:33 INFO mapred.JobClient: Counters: 19
14/10/07 18:56:33 INFO mapred.JobClient: File Output Format Counters
14/10/07 18:56:33 INFO mapred.JobClient: Bytes Written=21
14/10/07 18:56:33 INFO mapred.JobClient: FileSystemCounters
14/10/07 18:56:33 INFO mapred.JobClient: FILE_BYTES_READ=343
14/10/07 18:56:33 INFO mapred.JobClient: HDFS_BYTES_READ=42
14/10/07 18:56:33 INFO mapred.JobClient: FILE_BYTES_WRITTEN=129572
14/10/07 18:56:33 INFO mapred.JobClient: HDFS_BYTES_WRITTEN=21
14/10/07 18:56:33 INFO mapred.JobClient: File Input Format Counters
14/10/07 18:56:33 INFO mapred.JobClient: Bytes Read=21
14/10/07 18:56:33 INFO mapred.JobClient: Map-Reduce Framework
14/10/07 18:56:33 INFO mapred.JobClient: Map output materialized bytes=51
14/10/07 18:56:33 INFO mapred.JobClient: Map input records=2
14/10/07 18:56:33 INFO mapred.JobClient: Reduce shuffle bytes=0
14/10/07 18:56:33 INFO mapred.JobClient: Spilled Records=6
14/10/07 18:56:33 INFO mapred.JobClient: Map output bytes=53
14/10/07 18:56:33 INFO mapred.JobClient: Total committed heap usage (bytes)=391774208
14/10/07 18:56:33 INFO mapred.JobClient: SPLIT_RAW_BYTES=95
14/10/07 18:56:33 INFO mapred.JobClient: Combine input records=4
14/10/07 18:56:33 INFO mapred.JobClient: Reduce input records=3
14/10/07 18:56:33 INFO mapred.JobClient: Reduce input groups=3
14/10/07 18:56:33 INFO mapred.JobClient: Combine output records=3
14/10/07 18:56:33 INFO mapred.JobClient: Reduce output records=3
14/10/07 18:56:33 INFO mapred.JobClient: Map output records=4
图 3.2
从上面的运行结果我们可以得知,combine具体作用如下:
- 每一个map可能会产生大量的输出,combiner的作用就是在map端对输出先做一次合并,以减少传输到reducer的数据量。
- combiner最基本是实现本地key的归并,combiner具有类似本地的reduce功能。
- 如果不用combiner,那么,所有的结果都是reduce完成,效率会相对低下。使用combiner,先完成的map会在本地聚合,提升速度。
注意:Combiner的输出是Reducer的输入,Combiner绝不能改变最终的计算结果。所以从我的想法来看,Combiner只应该用于那 种Reduce的输入key/value与输出key/value类型完全一致,且不影响最终结果的场景。比如累加,最大值等。
解释一下
*问:为什么使用Combiner?
答:Combiner发生在Map端,对数据进行规约处理,数据量变小了,传送到reduce端的数据量变小了,传输时间变短,作业的整体时间变短。
* 问:为什么Combiner不作为MR运行的标配,而是可选步骤?
答:因为不是所有的算法都适合使用Combiner处理,例如求平均数。
* 问:Combiner本身已经执行了reduce操作,为什么在Reducer阶段还要执行reduce操作?
答:combiner操作发生在map端的,智能处理一个map任务中的数据,不能跨map任务执行;只有reduce可以接收多个map任务处理的数据。
三、Partitioner编程
4.1 什么是分区
在MapReuce程序中的Mapper任务的第三步就是分区,那么分区到底是干什么的呢?其实,把数据分区是为了更好的利用数据,根据数据的属性不同来分成不同区,再根据不同的分区完成不同的任务。MapReduce程序中他的默认分区是1个分区,我们看一下默认分区的代码,还是以单词统计为例如代码4.1所示。
package counter; import java.net.URI; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Counter;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.mapreduce.lib.partition.HashPartitioner; public class WordCountApp {
static final String INPUT_PATH = "hdfs://hadoop:9000/input";
static final String OUT_PATH = "hdfs://hadoop:9000/output"; public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); final FileSystem fileSystem = FileSystem.get(new URI(INPUT_PATH), conf);
final Path outPath = new Path(OUT_PATH); if(fileSystem.exists(outPath)){
fileSystem.delete(outPath, true);
}
final Job job = new Job(conf , WordCountApp.class.getSimpleName()); //1.1指定读取的文件位于哪里
FileInputFormat.setInputPaths(job, INPUT_PATH);
job.setInputFormatClass(TextInputFormat.class);//指定如何对输入文件进行格式化,把输入文件每一行解析成键值对 //1.2 指定自定义的map类
job.setMapperClass(MyMapper.class);
job.setMapOutputKeyClass(Text.class);//map输出的<k,v>类型。
job.setMapOutputValueClass(LongWritable.class);//如果<k3,v3>的类型与<k2,v2>类型一致,则可以省略 //1.3 分区
job.setPartitionerClass(HashPartitioner.class);
job.setNumReduceTasks(1);//有一个reduce任务运行 job.setCombinerClass(MyReducer.class);
//2.2 指定自定义reduce类
job.setReducerClass(MyReducer.class); job.setOutputKeyClass(Text.class);//指定reduce的输出类型
job.setOutputValueClass(LongWritable.class); //2.3 指定写出到哪里
FileOutputFormat.setOutputPath(job, outPath);
job.setOutputFormatClass(TextOutputFormat.class);//指定输出文件的格式化类 job.waitForCompletion(true);//把job提交给JobTracker运行
} /**
* KEYIN 即k1 表示行的偏移量
* VALUEIN 即v1 表示行文本内容
* KEYOUT 即k2 表示行中出现的单词
* VALUEOUT 即v2 表示行中出现的单词的次数,固定值1
*/
static class MyMapper extends Mapper<LongWritable, Text, Text, LongWritable>{
protected void map(LongWritable k1, Text v1, Context context) throws java.io.IOException ,InterruptedException {
final Counter helloCounter = context.getCounter("Sensitive Words", "hello"); final String line = v1.toString();
if(line.contains("hello")){
//记录敏感词出现在一行中
helloCounter.increment(1L);
}
final String[] splited = line.split("\t");
for (String word : splited) {
context.write(new Text(word), new LongWritable(1));
}
};
} /**
* KEYIN 即k2 表示行中出现的单词
* VALUEIN 即v2 表示行中出现的单词的次数
* KEYOUT 即k3 表示文本中出现的不同单词
* VALUEOUT 即v3 表示文本中出现的不同单词的总次数
*
*/
static class MyReducer extends Reducer<Text, LongWritable, Text, LongWritable>{
protected void reduce(Text k2, java.lang.Iterable<LongWritable> v2s, Context ctx) throws java.io.IOException ,InterruptedException {
long times = 0L;
for (LongWritable count : v2s) {
times += count.get();
}
ctx.write(k2, new LongWritable(times));
};
} }
代码 4.1
在MapReduce程序中默认的分区方法为HashPartitioner,代码job.setNumReduceTasks(1)表示运行的Reduce任务数,他会将numReduceTask这个变量设为1. HashPartitioner继承自Partitioner,Partitioner是Partitioner的基类,如果需要定制partitioner也需要继承该类。 HashPartitioner计算方法如代码4.2所示。
public class HashPartitioner<K, V> extends Partitioner<K, V> { /** Use {@link Object#hashCode()} to partition. */
public int getPartition(K key, V value,
int numReduceTasks) {
return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
} }
代码 4.2
在上面的代码中K和V,表示k2和v2,该类中只有一个方法getPartition(),返回值如下”(key.hashCode()& Integer.MAX_VALUE)%numReduceTasks“其中key.hashCode()表示该关键是否属于该类。numReduceTasks的值在上面代码中设置为1,取模后只有一种结果那就是0。getPartition()的意义就是表示划分到不同区域的一个标记,返回0,就是表示划分到第0区,所以我们可以把它理解分区的下标,来代表不同的分区。
4.2 自定义分区
下面我们尝试自定义一个分区,来处理一下手机的日志数据(在前面学习中用过),手机日志数据如下图4.1所示。
图 4.1
从图中我们可以发现,在第二列上并不是所有的数据都是手机号,我们任务就是在统计手机流量时,将手机号码和非手机号输出到不同的文件中。我们的分区是按手机和非手机号码来分的,所以我们可以按该字段的长度来划分,如代码4.3所示。
package partition; import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.mapreduce.lib.partition.HashPartitioner; public class KpiApp {
static final String INPUT_PATH = "hdfs://hadoop:9000/wlan";
static final String OUT_PATH = "hdfs://hadoop:9000/out";
public static void main(String[] args) throws Exception{
final Job job = new Job(new Configuration(), KpiApp.class.getSimpleName()); job.setJarByClass(KpiApp.class); //1.1 指定输入文件路径
FileInputFormat.setInputPaths(job, INPUT_PATH);
job.setInputFormatClass(TextInputFormat.class);//指定哪个类用来格式化输入文件 //1.2指定自定义的Mapper类
job.setMapperClass(MyMapper.class);
job.setMapOutputKeyClass(Text.class);//指定输出<k2,v2>的类型
job.setMapOutputValueClass(KpiWritable.class); //1.3 指定分区类
job.setPartitionerClass(KpiPartitioner.class);
job.setNumReduceTasks(2); //2.2 指定自定义的reduce类
job.setReducerClass(MyReducer.class);
job.setOutputKeyClass(Text.class);//指定输出<k3,v3>的类型
job.setOutputValueClass(KpiWritable.class); //2.3 指定输出到哪里
FileOutputFormat.setOutputPath(job, new Path(OUT_PATH));
job.setOutputFormatClass(TextOutputFormat.class);//设定输出文件的格式化类
job.waitForCompletion(true);//把代码提交给JobTracker执行
} static class MyMapper extends Mapper<LongWritable, Text, Text, KpiWritable>{
protected void map(LongWritable key, Text value, org.apache.hadoop.mapreduce.Mapper<LongWritable,Text,Text,KpiWritable>.Context context) throws IOException ,InterruptedException {
final String[] splited = value.toString().split("\t");
final String msisdn = splited[1];
final Text k2 = new Text(msisdn);
final KpiWritable v2 = new KpiWritable(splited[6],splited[7],splited[8],splited[9]);
context.write(k2, v2);
};
} static class MyReducer extends Reducer<Text, KpiWritable, Text, KpiWritable>{
/**
* @param k2 表示整个文件中不同的手机号码
* @param v2s 表示该手机号在不同时段的流量的集合
*/
protected void reduce(Text k2, java.lang.Iterable<KpiWritable> v2s, org.apache.hadoop.mapreduce.Reducer<Text,KpiWritable,Text,KpiWritable>.Context context) throws IOException ,InterruptedException {
long upPackNum = 0L;
long downPackNum = 0L;
long upPayLoad = 0L;
long downPayLoad = 0L; for (KpiWritable kpiWritable : v2s) {
upPackNum += kpiWritable.upPackNum;
downPackNum += kpiWritable.downPackNum;
upPayLoad += kpiWritable.upPayLoad;
downPayLoad += kpiWritable.downPayLoad;
} final KpiWritable v3 = new KpiWritable(upPackNum+"", downPackNum+"", upPayLoad+"", downPayLoad+"");
context.write(k2, v3);
};
} static class KpiPartitioner extends HashPartitioner<Text, KpiWritable>{
@Override
public int getPartition(Text key, KpiWritable value, int numReduceTasks) {
return (key.toString().length()==11)?0:1;
}
}
} class KpiWritable implements Writable{
long upPackNum;
long downPackNum;
long upPayLoad;
long downPayLoad; public KpiWritable(){} public KpiWritable(String upPackNum, String downPackNum, String upPayLoad, String downPayLoad){
this.upPackNum = Long.parseLong(upPackNum);
this.downPackNum = Long.parseLong(downPackNum);
this.upPayLoad = Long.parseLong(upPayLoad);
this.downPayLoad = Long.parseLong(downPayLoad);
} @Override
public void readFields(DataInput in) throws IOException {
this.upPackNum = in.readLong();
this.downPackNum = in.readLong();
this.upPayLoad = in.readLong();
this.downPayLoad = in.readLong();
} @Override
public void write(DataOutput out) throws IOException {
out.writeLong(upPackNum);
out.writeLong(downPackNum);
out.writeLong(upPayLoad);
out.writeLong(downPayLoad);
} @Override
public String toString() {
return upPackNum + "\t" + downPackNum + "\t" + upPayLoad + "\t" + downPayLoad;
}
}
代码 4.3
注意:分区的例子必须打成jar运行,运行结果如下图4.3,4.4所示,4.3表示手机号码流量,4.4为非手机号流量。
图 4.3
aaarticlea/png;base64,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" alt="" />
图4.4
我们知道一个分区对应一个Reducer任务是否是这样呢,我可以通过访问50030MapReduce端口来验证,在浏览器输入”http://hadoop:50030"可以看到MapReduce界面,如图4.5,4.6所示。
图 4.5
aaarticlea/png;base64,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" alt="" width="646" height="323" />
图4.6
从图中可以知道,该MapReduce任务有一个Mapper任务,两个Reducer任务,那么我们细看一下Reducer的两个任务到底是什么?如图4.7,4.8,4.9所示。task_201410070239_0002_r_000000表示第一个分区的输出,有20条记录,task_201410070239_0002_r_000001表示第二分区,有一条输出记录。和我们程序运行结果一样。
图 4.7
aaarticlea/png;base64,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" alt="" width="624" height="247" />
图 4.8 第一分区
aaarticlea/png;base64,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" alt="" width="635" height="287" />
图 4.9 第二分区
综上一些列分析,分区的用处如下:
1.根据业务需要,产生多个输出文件
2.多个reduce任务在并发运行,提高整体job的运行效率
Hadoop日记Day17---计数器、map规约、分区学习的更多相关文章
- Hadoop日记系列目录
下面是Hadoop日记系列的目录,由于目前时间不是很充裕,以后的更新的速度会变慢,会按照一星期发布一期的原则进行,希望能和大家相互学习.交流. 目录安排 1> Hadoop日记Day1---H ...
- splittability A SequenceFile can be split by Hadoop and distributed across map jobs whereas a GZIP file cannot be.
splittability CompressedStorage Skip to end of metadata Created by Confluence Administrator, l ...
- Hadoop日记Day12---MapReduce学习
一.MapReduce简介 1.1MapReduce概述 MapReduce是一种分布式计算模型,由Google提出,主要用于搜索领域,解决海量数据的计算问题.MR由两个阶段组成:Map和Reduce ...
- pwn学习日记Day17 《程序员的自我修养》读书笔记
静态链接章小结 本章首先学习了静态链接的第一步骤,即目标文件在被链接成最终可执行文件时,输入目标文件中的各段是如何被合并到输出文件中的,链接器如何为它们分配在输出文件中的空间和地址.一旦输入段中的最终 ...
- Hadoop日记Day15---MapReduce新旧api的比较
我使用hadoop的是hadoop1.1.2,而很多公司也在使用hadoop0.2x版本,因此市面上的hadoop资料版本不一,为了扩充自己的知识面,MapReduce的新旧api进行了比较研究. h ...
- Hadoop日记Day13---使用hadoop自定义类型处理手机上网日志
测试数据的下载地址为:http://pan.baidu.com/s/1gdgSn6r 一.文件分析 首先可以用文本编辑器打开一个HTTP_20130313143750.dat的二进制文件,这个文件的内 ...
- Hadoop MapReduce 保姆级吐血宝典,学习与面试必读此文!
Hadoop 涉及的知识点如下图所示,本文将逐一讲解: 本文档参考了关于 Hadoop 的官网及其他众多资料整理而成,为了整洁的排版及舒适的阅读,对于模糊不清晰的图片及黑白图片进行重新绘制成了高清彩图 ...
- Hadoop日记Day18---MapReduce排序分组
本节所用到的数据下载地址为:http://pan.baidu.com/s/1bnfELmZ MapReduce的排序分组任务与要求 我们知道排序分组是MapReduce中Mapper端的第四步,其中分 ...
- Hadoop日记Day1---Hadoop介绍
一.Hadoop项目简介 1. Hadoop是什么 Hadoop是一个适合大数据的分布式存储与计算平台. 作者:Doug Cutting:Lucene,Nutch. 受Google三篇论文的启发 2. ...
随机推荐
- SQL Server日期时间格式转换字符串详解 (详询请加qq:2085920154)
在SQL Server数据库中,SQL Server日期时间格式转换字符串可以改变SQL Server日期和时间的格式,是每个SQL数据库用户都应该掌握的.本文我们主要就介绍一下SQL Server日 ...
- Bash Shell字符串操作
转自:http://my.oschina.net/aiguozhe/blog/41557,并对内容作了验证修改. 1. 取长度 str="abcd" 2.查找子串的位置 貌似也只有 ...
- CMake 使用方法(转)
CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程).他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的 ...
- 炫酷CSS
<!DOCTYPE html><!--To change this license header, choose License Headers in Project Propert ...
- AngularJS四大特性
Google AnguarJS是一个JS框架,适用于以数据的CRUD操作为主的SPA应用. 四大特性: (1)MVC模型 Model:模型,即数据=>JS中的变量 View:视图,即数据的呈现= ...
- button、label、textfield、页面跳转、传值
.AppDelegate.m #import “OneViewController.h” //一打开就运行的 -(BOOL)application:(UIApplication *)applicati ...
- poj3728
[描述] 有 N 城 市在一个国家,有一个且只有一个简单的路径每一对城市之间. 一个商人选择了一些路径和想赚尽可能多的钱在每个路径. 当他沿着一条路径,可以选择一个城市购买一些商品和出售他们在一个城市 ...
- Win7 64位 VS2015及MinGW环境编译FFMPEG-20160326
因为又要弄MinGW了,所以顺便把FFMPEG编译了,文章主要参考这篇,防抽所以复制一遍,顺便加些自己的内容 http://blog.csdn.net/finewind/article/details ...
- SQL一致性错误修复SQL
USE master; ); SET @databasename = 'BenlaiTask'; ALTER DATABASE BenlaiTask SET SINGLE_USER WITH ROLL ...
- Discuz!X2大附件上传插件-Xproer.HttpUploader6
插件代码(github):https://github.com/1269085759/up6-discuz 插件代码(coding):https://coding.net/u/xproer/p/up6 ...