MapReduce是一个软件框架没采用并行、分布式处理GB、tb的数据,同时也是一个在商用服务器集群上完成大规模数据处理的执行框架,由google提出,目标是实现可伸缩性
使用MapReduce时,重点是编写两个函数:
map()映射 过滤和聚集数据 (key1,value1)->(key2,value2)
主节点得到输入后,将输入划分为较小的数据块,将这些数据块分不到工作节点上,工作节点对每个数据块应用相同的转换函数,然后将结果传回到主节点
reduce()规约 根据map生成的键进行规约、分组和操作(key2,[value2])->(key3,value3)
主节点根据键值对将接受的结果进行洗牌和聚集,在重新分不到工作节点,通过reduce转换。
MapReduce不是一个编程语言,而是一个框架,可以使用java,scala 等在这个框架上开发分布式应用
MapReduce的分布式文件系统不能取代关系数据库系统,MapReduce的输入一般是纯文本文件
MapReduce主要设计用于批处理。
hadoop是MapReduce应用实现的事实标准。hadoop和spark是两个不同的分布式软件框架。hadoop是一个MapReduce框架,支持map、combine、reduce。spark不是一个MapReduce框架,但很容易用来支持MapReduce框架的功能,提供一个适当的api处理map和reduce功能。spark可以使用hadoop运行,也可以不适用。spark可以使用HDFS或其他存储实现输入输出。
单词计数
public class WordCount {
//继承mapper接口,定义输入输出类型
public static class TokenizerMapper
extends Mapper<Object, Text,Text,IntWritable>{
//定义int类型的输出变量
private final static IntWritable one =new IntWritable(1);
//word 存储切下的单词
private Text word =new Text();
public void map(Object Key, Text value, Context context) throws IOException, InterruptedException{
StringTokenizer itr = new StringTokenizer(value.toString()); //对输入的行切词
while (itr.hasMoreTokens()){
word.set(itr.nextToken()); //切下的单词存入word
context.write(word,one);
}
}
}
//继承reducer接口,设置reduce的输入和输出类型
public static class IntSumReducer extends Reducer<Text,IntWritable,Text,IntWritable>{
private IntWritable result = new IntWritable();
public void reduce(Text key, Iterable<IntWritable> values, Context context)
throws IOExecption InterruptedException{
int sum =0;
//对获取的key values计算values的和
for (IntWritable val:values){
sum +=val.get()
}
result.set(sum);
context.write(key,result);
}
}
public static void main(String[] args) throws Exception{
Configuration conf = new Configuration();
String[] otherArgs= new GenericOptionsParser(conf, args).getRemainingArgs();
if (otherArgs.length !=2){
System.err.println("usage:wordcount <in><out>")
System.exit(2);
}
Job job =new Job(conf,"word count");
job.setJarByClass(WordCount.class);
job.setMapperClass(TokenizerMapper.class);
job.setCombinerClass(IntSumReducer.class);
job.setReducerClass(IntSumReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job,new Path(otherArgs[0]));
FileOutputFormat.setOutputPath(job,new Path(otherArgs[1]));
System.exit(job.waitForCompletion(true)? 0:1)
}
}
//运行
bin/hadoop fs -mkdir input // 在集群上创建输入文件夹
bin/hadoop fs -put input/file* input // 上传文件到集群input下
javac -classpath hadoop-0.20.2-core.jarl
lib/commons-cli-1.2.jar -d wordcount wordcount.java // 编译wordcount.java 程序,将结果放入当前目录的worcount目录下
jar -cvf wordcount.jar -C wordcount //将编译结果打包
bin/hadoop jar wordcount.jar wordcount input output //在集群上运行wordcount程序,以input目录为输入目录,output为输出目录