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
//针对这里我用的Set集合去除重复的功能
Set
//在这里遍历注意一点,地址覆盖
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
目前只接触到这两种