一.HDFS数据格式
1.文件格式
2.压缩格式
3.设置mr的输出格式
例子:设置输出格式为gzip
shell命令启动时要携带对应的参数:
# 命令太长时 可以用 \ 新开一行
yarn jar aaa.jar com.aaa.main.Wordcount \
-Dmapred.output.compress=true \
-Dmapred.output.compression.codec=org.apache.hadoop.io.compressGzipCodec \
输入路径 输出路径
启动类读取-D后面的参数
//启动mr的driver方法
public static void main(String[] args) throws Exception {
//得到集群配置参数
Configuration conf = new Configuration();
//参数解析器
GenericOptionsParser optionParser = new GenericOptionsParser(conf, args);
//获取正常的参数(-D后面的参数会被自动解析,其他的参数可以通过以下方法获取)
String[] remainingArgs = optionParser.getRemainingArgs();
//设置到本次的job实例中
Job job = Job.getInstance(conf, "WordCount");
//指定本次执行的主类是WordCount
job.setJarByClass(WordCount.class);
//指定map类
job.setMapperClass(TokenizerMapper.class);
//指定combiner类,要么不指定,如果指定,一般与reducer类相同
job.setCombinerClass(IntSumReducer.class);
//指定reducer类
job.setReducerClass(IntSumReducer.class);
//指定job输出的key和value的类型,如果map和reduce输出类型不完全相同,需要重新设置map的output的key和value的class类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
//指定输入数据的路径
FileInputFormat.addInputPath(job, new Path(remainingArgs[0]));
//指定输出路径,并要求该输出路径一定是不存在的
FileOutputFormat.setOutputPath(job, new Path(remainingArgs[1]));
//指定job执行模式,等待任务执行完成后,提交任务的客户端才会退出!
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
二.MR自定义Partition
1.Partition的默认HashPartition
public class HashPartitioner<K, V> extends Partitioner<K, V> {
public int getPartition(K key, V value, int numReduceTasks) {
//这里与上int的最大值可numReduceTasks由系统决定,也可以手动设置以防止负数产生
//numReduceTasks由系统决定,也可以手动设置
//partition的作用就是让kv均匀的分布到reduce节点中
return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
}
}
2.MapReduce个数的确定时机
在Job提交后,任务正式开始计算之前即已经确定
Map数量的确定:由输入数据文件的总大小、数据格式、块大小综合确定
Reduce数量确定:系统根据输入数据量的大小自动确定,有固定的计算公式
3.自定义Reduce数量
启动参数如下:
-Dmapred.reduce.tasks=2
4.自定义partition的实现
通过继承Partitioner类,自定义实现Partition
public static class MyPartitioner<K, V> extends Partitioner<K, V> {
public int getPartition(K key, V value, int numReduceTasks) {
//最后会产生两个文件,part0和part1
if(k==0){
return 0;
}else{
return 1;
}
}
}
启动类要指定一下子
job.setPartitionerClass(MyPartitioner.class);
启动时指定reduce的数量
-Dmapred.reduce.tasks=2
注意:分区数量一定要和reduce数量保持一致,否则分区无任何意义(只会生成一个文件)
三.MR之读取外部配置文件
在某些时候我们想让多个map节点共享同一份数据(黑名单或者白名单过滤等场景)
这时候就可以将外部文件读取到全局上下文中实现数据共享
步骤:
将需要共享的数据写入到上下文中
Configuration conf = new Configuration();
conf.set("key", source);
在map中使用全局数据
//每个map任务有且仅会执行一次setup方法,用于初始化map函数执行前的所需参数
String shareData;
@Override
protected void setup(Mapper<Object, Text, Text, IntWritable>.Context context) throws IOException, InterruptedException {
Configuration conf = context.getConfiguration();
//读取共享数据
shareData = conf.get("key");
}