理解mapReduce之前,需要先知道Yarn
yarn:资源管理器,主从架构,所有的mapReduce的资源调用都是Yarn分配的。Yarn有三大概念:ResourceManager,ApplicationMaster,NodeManager’。
ResourceManager:分配和调度资源;启动并监控ApplicationMaster;监控nodeManager
ApplicationMaster:为MR类型的程序申请资源,并分配给内部任务;负责任务数据的切分;监控任务的执行及容错
NodeManager:管理单个节点的资源;处理来自ResourceManager命令;处理来自ApplicationMaster的命令
MapReduce的编程方法:
1.输入一个大文件,通过split之后,分成多少片?
2.每个文件分片有单独的机器去处理,这是map方法
3.各个机器计算结果汇总,并得到最终结果,这是reduce方法
有个很形象生动的图可以表达整个过程:
每次看这个图,都能感受到广大劳动人民的智慧是多么。
我们现在有这么个文件:`
时间戳 手机号 手机的mac地址CMCC-EASY移动 访问的ip地址 访问的网站 访问的渠道 上行数据包 下行数据包 上行流量 下行流量 状态码
1363157984040 13602846565 5C-0E-8B-8B-B6-00:CMCC 120.197.40.4 2052.flash2-http.qq.com 综合门户 15 12 1938 2910 200
1363157995093 13922314466 00-FD-07-A2-EC-BA:CMCC 120.196.100.82 img.qfc.cn 12 12 3008 3720 200
1363157982040 13502468823 5C-0A-5B-6A-0B-D4:CMCC-EASY 120.196.100.99 y0.ifengimg.com 综合门户 57 102 7335 110349 200
1363157986072 18320173382 84-25-DB-4F-10-1A:CMCC-EASY 120.196.100.99 input.shouji.sogou.com 搜索引擎 21 18 9531 2412 200
求手机号的总流量之后并进行排序,我们可以封装一个bean类,
public class SortBean implements WritableComparable<SortBean> {
long upflow;//上行流量
long downflow;//下行流量
long sumflow;//总量
public SortBean() {
super();
}
public SortBean(long upflow, long downflow, long sumflow) {
super();
this.upflow = upflow;
this.downflow = downflow;
this.sumflow = sumflow;
}
@Override
public String toString() {
return upflow+"\t"+downflow+"\t"+sumflow;
}
public long getUpflow() {
return upflow;
}
public void setUpflow(long upflow) {
this.upflow = upflow;
}
public long getDownflow() {
return downflow;
}
public void setDownflow(long downflow) {
this.downflow = downflow;
}
public long getSumflow() {
return sumflow;
}
public void setSumflow(long sumflow) {
this.sumflow = sumflow;
}
@Override
public void write(DataOutput out) throws IOException {
out.writeLong(upflow);
out.writeLong(downflow);
out.writeLong(sumflow);
}
@Override
public void readFields(DataInput in) throws IOException {
upflow = in.readLong();
downflow = in.readLong();
sumflow=in.readLong();
}
@Override
public int compareTo(SortBean o) {
if(this.sumflow>o.sumflow){
return -1;
}else if(this.sumflow<o.sumflow){
return 1;
}else if(this.downflow>o.downflow){
return -1;
}else if(this.downflow<o.downflow){
return 1;
}else{
return 1;
}
}
}
map方法对数据切片:
public class SortMapper extends Mapper<LongWritable, Text, SortBean, Text>{
@Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, SortBean, Text>.Context context)
throws IOException, InterruptedException {
String[] words=value.toString().split("\t");//切片
SortBean sortBean=new SortBean(Long.parseLong(words[words.length-3]),Long.parseLong(words[words.length-2]),Long.parseLong(words[words.length-1]));//上行流量 在倒数第三个length-2,下行流量在倒数第二个length-1
context.write(sortBean, new Text(words[0]));
}
}
reduce方法合并;
public class SortReduce extends Reducer<SortBean, Text, Text, SortBean>{
@Override
protected void reduce(SortBean arg0, Iterable<Text> arg1, Reducer<SortBean, Text, Text, SortBean>.Context arg2)
throws IOException, InterruptedException {
Text phone=null;
for (Text text : arg1) {
phone=text;
}
arg2.write(phone , arg0);
}
}
job运行:
public class SortCountRunner {
//把这个描述好的job提交给集群去运行
public static void main(String[]args) throws IOException, ClassNotFoundException, InterruptedException {
//配置文件
Configuration conf = new Configuration();
Job job=Job.getInstance(conf);
//指定这个job所在的jar包
job.setJarByClass(SortCountRunner.class);
job.setMapperClass(SortMapper.class);
job.setReducerClass(SortReduce.class);
//设置我们业务逻辑Mapper类的输出key和value的数据类型
job.setMapOutputKeyClass(SortBean.class);
job.setMapOutputValueClass(Text.class);
//设置我们业务逻辑Reduce类的输出key和value的数据类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(SortBean.class);
//指定要处理的数据所在位置
FileInputFormat.setInputPaths(job, args[0]);
//指定处理完成之后的结果所保存的位置
FileOutputFormat.setOutputPath(job, new Path(args[1]));
//\向yarn集群提交这个job
job.waitForCompletion(true);
}
}
生成主类的jar放在根目录下,将要执行的文件放在hdfs上,
开启yarn
执行
hadoop jar hadoop-mapreduce-examples-2.7.3.jar wordcount /data/input/word.txt /data/output/
hadoop jar—命令 执行jar文件
hadoop-mapreduce-examples-2.7.3.jar jar包的名称
wordcount 要执行那个一个类,如果导jar的时候已经指定主类,可以省略
/data/input/word.txt 被计算的目录
/data/output/ 计算结果输出的目录
结果输出在hdfs上