Hadoop_MapReducer_简单实用与实例

Mapper

import java.io.IOException;

 

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
/**
 * 值得类型   个人理解
 * LongWritable  整数类型
 * IntWritable   整数类型
 * NullWritable  如果输出的键/值为空类型用这个
 * Text    类似String类型
 *mapper里面的四个值
 *第一个值是行的偏移量  整性
 *第二个是行的内容
 *第三个是发送到reducer的行内容的类型 我理解的是每次发送一行 可能有误 谅解
 *第四个是发送到reducer的键的类型,相当于行内容的描述信息,比如次数等等
 */
public class FileMapper extends Mapper {

 public void map(LongWritable ikey, Text ivalue, Context context) throws IOException, InterruptedException {
  //行内容转化为String类型进行操作,发送时在转化为对应的类型
  String line = ivalue.toString(); 
  String[] arr = line.split(" ");
  //这个例子取得是每个单词的目录名 
  //下面两行是得到目录名的方法
  FileSplit fs = (FileSplit) context.getInputSplit();
  String name = fs.getPath().getName();
  //遍历输出
  for (int i = 0; i < arr.length; i++) {
   context.write(new Text(arr[i]), new Text(name));
  }
 }
}

Reducer 

 

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

 

import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
/**
 * 第一个和第二个类型对应Mapper发送的数据键/值类型
 * 第三个和第四个类型对应输出到文本的键/值类型
 */
public class FileReducer extends Reducer {

 

 public void reduce(Text _key, Iterable values, Context context) throws IOException, InterruptedException {
  //针对这里我用的Set集合去除重复的功能
  Set f = new HashSet<>();
  //在这里遍历注意一点,地址覆盖
  
  for (Text val : values) {
   f.add(val.toString());
  }
  context.write(_key, new Text(f.toString()));
 }

}
//demo  取出key对应的最大的值
//IntWritable max= new IntWritable(0);
////地址复用   max和val公用一个地址
//for (IntWritable val : values) {
// if(max.get() < val.get()){
//  max = val;       //这里用的地址覆盖所以是取不到最大值的
// }
//}
//context.write(_key, max);

 Driver

 

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

 

public class FileDriver {

 

 public static void main(String[] args) throws Exception {
  Configuration conf = new Configuration();
  Job job = Job.getInstance(conf, "JobName");
  job.setJarByClass(com.hdfs.demo.FileDriver.class);
  //对应的Mapper和Reducer
  job.setMapperClass(FileMapper.class);
  //job.setMapOutputKeyClass(类型.class);
  //job.setMapOutputValueClass(类型.class);
  job.setReducerClass(FileReducer.class);
  //这里是Mapper和Reducer的输出类型  如果类型一致修改对应的类型即可 
  job.setOutputKeyClass(Text.class);
  job.setOutputValueClass(Text.class);
  //job=分配的一个task,就是tasktracker执行操作
  //一个读数据进行操作 Mapper 读数据 解析成K-V结构
  //一个计算数据进行操作 Reduer 操作数据 输出到不同分区的文件中
  FileInputFormat.setInputPaths(job, new Path("hdfs://192.168.153.129:9000/demo/txt/invert"));
  FileOutputFormat.setOutputPath(job, new Path("hdfs://192.168.153.129:9000/demoresult/invert"));

 

  if (!job.waitForCompletion(true))
   return;
 }

}序列化/反序列化

 有些数据普通类型已经表示不了它的整体信息,因此进行封装,封装完成Hadoop不认识,因此需要序列化和反序列化进行输入和输出

就是一个普通的javabean 实现了Writable接口,重写里面的方法

@Override
 public void readFields(DataInput in) throws IOException {
  this.name = in.readUTF();
  this.age = in.readInt();
 }
 @Override
 public void write(DataOutput out) throws IOException {
  out.writeUTF(name);
  out.writeInt(age);
 }

String类型对于UTF

int类型对应int

目前只接触到这两种

 

你可能感兴趣的:(Hadoop)