一、准备:

eclipse,hadoop集群

注意:为了方便测试和修改,我用的是 windows 连接hadoop集群,这样在windows 下直接就能够执行 mapreduce 任务,方便程序调试。在 windows 下执行 mapreduce 任务需要安装相关插件,可以参考  
windows连接hadoop集群下执行MapReduce任务

数据下载地址:数据下载

密码:idnx

二、分析

本案例的数据来自某搜索引擎开放出来的部分搜索数据,数据格式如下:

20111230104334    966a6bf4c4ec1cc693b6e40702984235    X档案研究所TXT下载    4    2    http://www.readist.cn/book/dl024708.html

分别有6个字段:时间,id,关键词,该URL在返回结果中的排名,用户点击顺序号,点击的URL。每个字段之间用 \t 分隔。

现在需要统计独立 UID 的总数,也就是说要将 UID 去重,然后累加。用 mapreduce 编程思想可以看作先执行一个mapreduce 任务将 UID 去重,再执行一个 mapreduce 任务将去重后的数据累加。所以这里要执行两个mapreduce 任务,这两个mapreduce 任务是串行运行的。

三、实现

实现分两个部分,第一部分是对UID去重,第二部分是对去重后的UID累加。第一部分的输出结果作为第二部分的输入结果。

第一部分:

1.首先执行的是去重过程,去重的过程实际上就是wordcount 的过程,Map 函数先将输入的数据标记成 key-value 键值对,其中key 是行号,value 是这一行的值,然后设置我们要统计的列类,并对这个列进行标记,Map函数的输出结果类似于如下所示:

(966a6bf4c4ec1cc693b6e40702984232,1)

(966a6bf4c4ec1cc693b6e40702984235,1)

(966a6bf4c4ec1cc693b6e40702984235,1)...

2.Reduce 的过程是对 Map 过程的一个累加,将 value 累加在一起,得出结果。

public static class MyMapper1 extends Mapper<Object, Text, Text, IntWritable> {

		@Override
protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {
IntWritable One = new IntWritable(1);
Text k1 = new Text("");
String line = value.toString();
String[] data = line.split("\t");
if (data != null || data.length == 6) {
String uid = data[1];
k1.set(uid);
context.write(k1, One);
}
}
} public static class MyReduce1 extends Reducer<Text, IntWritable, Text, IntWritable> { @Override
protected void reduce(Text key, Iterable<IntWritable> value, Context context)
throws IOException, InterruptedException {
int sum = 0;
for (IntWritable iw : value) {
sum += iw.get();
}
context.write(key, new IntWritable(sum)); }
}

输出结果是对UID的一个统计,这个过程实现了UID的去重,第一列就是去重后的UID,部分结果如下:

000048ad4cb133b2bb376f07356dde9e    6

00005c113b97c0977c768c13a6ffbb95    2

000064b4c0f12cfb69cb4646835c6544    1

第二部分:

1.在第一部分的中,得到了去重后的UID和数量,我们只需要第一列数据,即去重后的UID。

这部分的重点是统计去重后的UID的数量。

2.第一部分的结果输出作为第二部分的结果输入,所以在Map


过程中我们只需要将第二个字段的数据重置为 1 即可,这里定义了新的 key , key 的值是“独立uid的数量是:”,value 是 1 ,写成键值对的形式就是:(独立uid的数量是:,1)

Map 函数的输出结果是:

独立uid的数量是:    1

独立uid的数量是:    1

独立uid的数量是:    1

reduce的过程是对 Map 的输出结果的累加,即对 “1” 的累加,输出结果就是我们的最终结果:

独立uid的数量是:    13526

public static class MyMapper2 extends Mapper<Object, Text, Text, IntWritable> {

		@Override
protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {
IntWritable One = new IntWritable(1);
Text key1=new Text("独立uid的数量是 :");
context.write(key1, One);
}
} public static class MyReduce2 extends Reducer<Text, IntWritable, Text, IntWritable> { @Override
protected void reduce(Text key, Iterable<IntWritable> value, Context context)
throws IOException, InterruptedException {
int sum = 0;
for (IntWritable iw : value) {
sum += iw.get();
}
context.write(key, new IntWritable(sum));
}
}

以上过程就是mapreduce的串行执行过程。完整程序如下:

package com.sosuo;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class UuidNumber {
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
Configuration conf = new Configuration();
Job job1 = new Job(conf, "dlUid");
job1.setJarByClass(UuidNumber.class);
job1.setMapperClass(MyMapper1.class);
job1.setReducerClass(MyReduce1.class);
job1.setOutputKeyClass(Text.class);
job1.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job1, new Path(args[0]));
FileOutputFormat.setOutputPath(job1, new Path(args[1]));
job1.waitForCompletion(true); Job job2 = new Job(conf, "dlUid");
job2.setJarByClass(UuidNumber.class);
job2.setMapperClass(MyMapper2.class);
job2.setReducerClass(MyReduce2.class);
job2.setOutputKeyClass(Text.class);
job2.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job2, new Path(args[1]));
FileOutputFormat.setOutputPath(job2, new Path(args[2]));
job2.waitForCompletion(true); } public static class MyMapper1 extends Mapper<Object, Text, Text, IntWritable> { @Override
protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {
IntWritable One = new IntWritable(1);
Text k1 = new Text("");
String line = value.toString();
String[] data = line.split("\t");
if (data != null || data.length == 6) {
String uid = data[1];
k1.set(uid);
context.write(k1, One);
}
}
} public static class MyReduce1 extends Reducer<Text, IntWritable, Text, IntWritable> { @Override
protected void reduce(Text key, Iterable<IntWritable> value, Context context)
throws IOException, InterruptedException {
int sum = 0;
for (IntWritable iw : value) {
sum += iw.get();
}
context.write(key, new IntWritable(sum)); }
} public static class MyMapper2 extends Mapper<Object, Text, Text, IntWritable> { @Override
protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {
IntWritable One = new IntWritable(1);
Text key1=new Text("独立uid的数量是:");
context.write(key1, One);
}
} public static class MyReduce2 extends Reducer<Text, IntWritable, Text, IntWritable> { @Override
protected void reduce(Text key, Iterable<IntWritable> value, Context context)
throws IOException, InterruptedException {
int sum = 0;
for (IntWritable iw : value) {
sum += iw.get();
}
context.write(key, new IntWritable(sum));
}
}
}

要注意的是输入路径和输出路径,有三个路径,其中第一个是输入路径,第二个是中间结果的保存路径,即第一个mapreduce任务的输出结果,第三个是最终结果的路径。keke~

实例理解mapreduce任务的串行运行过程的更多相关文章

  1. MFC【6】文件I/O和串行化

    文件输入和输出(I/O)服务是所有操作系统的主要工作.Microsoft Windows提供了各种API函数用来读.写和操作磁盘文件.MFC将这些桉树和CFile类融合在面对对象的模型里.其中CFil ...

  2. servlet串行拦截器实现例子

    至于串行过滤器有什么作用,我实在不知.我的理解是它只是说明 过滤器的串行运行方式 需求:当用户没有登录访问更新页面的时候,跳转到登录页面 1.登录页面:login.jsp <%@ page la ...

  3. Linux 串行终端,虚拟终端,伪终端,控制终端,控制台终端的理解

    转自Linux 串行终端,虚拟终端,伪终端,控制终端,控制台终端的理解 终端:输入和输出设备(键盘 + 显示器). 串行终端:与机器的串口对应,每一个串口对应一个串行终端,串口对应的是物理终端. 虚拟 ...

  4. Hadoop日记Day16---命令行运行MapReduce程序

    一.代码编写 1.1 单词统计 回顾我们以前单词统计的例子,如代码1.1所示. package counter; import java.net.URI; import org.apache.hado ...

  5. GCD网络多线程---同步运行,异步运行,串行队列,并行队列

    总结:同步(无论是串行还是并行)----不又一次开辟子线程 异步(无论是串行还是并行)----开辟子线程 GCD: dispatch queue 主线程的main queue 并行队列 global ...

  6. iOS:GCD理解1(同步-异步、串行-并行)

    1.并行-异步(ST1与ST2抢占资源) 1-1).获取 并行(全局)队列 ,DISPATCH_QUEUE_PRIORITY_DEFAULT 为默认优先级. dispatch_queue_t queu ...

  7. iOS:GCD理解1(串行-并行、同步-异步)

    1.获取并行.创建串行 队列 1-1).获取 并行(全局) 队列 ,DISPATCH_QUEUE_PRIORITY_DEFAULT 为默认优先级. dispatch_queue_t global_qu ...

  8. iOS 多线程的简单理解(2) 队列 :串行 ,并行,MainQueue,GlobalQueue

    多线程队列是装载线程任务的队形结构.(系统以先进先出的方式调度队列中的任务执行 FIFO).在GCD中有两种队列: 串行队列.并发队列. 队列 :串行队列.并发队列,全局主对列,全局并发队列 2.1. ...

  9. MapReduce的ReduceTask任务的运行源码级分析

    MapReduce的MapTask任务的运行源码级分析 这篇文章好不容易恢复了...谢天谢地...这篇文章讲了MapTask的执行流程.咱们这一节讲解ReduceTask的执行流程.ReduceTas ...

随机推荐

  1. 使用gc、objgraph干掉python内存泄露与循环引用!

    Python使用引用计数和垃圾回收来做内存管理,前面也写过一遍文章<Python内存优化>,介绍了在python中,如何profile内存使用情况,并做出相应的优化.本文介绍两个更致命的问 ...

  2. div内部实现图片旋转、放大、缩小、拖拽

    药药,切克闹,一人我编码累,累把那bug写成堆.秋高气爽空气干燥你一定dei多喝水,过完了这周我就要回去.趁还有几天.你尽情的来跟我怼~~~ 新的一年,很久没更博客了,眼看十一要来了,听说过了十一就等 ...

  3. java学习——java按值传递和按址传递

    先复制一个面试/笔试的题: 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 答案: 是值传递.Java语言的方法调用只支持参 ...

  4. windows下实现linux的远程访问以及linux上文件的上传和下载

    在网络性能.安全性.可管理性上,Linux有着其他系统无法比拟的强大优势,而服务器对这些方面要求特别高,因此Linux常常被用来做服务器使用.而当我们需要维护linux服务器的时候,就需要远程访问li ...

  5. ajax url参数中文乱码解决方法

    较好的处理办法,对js的url中的中文参数值使用两次encodeURI(),即encodeURI(encodeURI("url的中文参数值")) JS代码: var name=&q ...

  6. JS表单提交的几种方式

    第一种方式 : 表单提交,在 form 标签中增加 onsubmit 事件来判断表单是否提交成功 <script type="text/javascript"> fun ...

  7. Centos7安装Percona5.7

    OS: Centos7.0 DB: Percona5.7 1. 通过yum安装 ## 删除之前的mysql数据库, 我用的是centos7.再安装虚拟机的时候,预装了很多软件.所以mysql和mari ...

  8. Python selenium 文件自动下载 (自动下载器)

    MyGithub:https://github.com/williamzxl 最新代码已经上传到Github,以下版本为stupid版本. 由于在下载过程中需要下载不同文件,所以可以把所有类型放在Va ...

  9. zoj 1938 Binomial Showdown 组合数裸基础

    Binomial Showdown Time Limit: 2 Seconds      Memory Limit: 65536 KB In how many ways can you choose ...

  10. ubuntu环境下lnmp环境搭建(3)之Php

    1.lnmp详细  http://www.discuz.net/thread-3513107-1-1.html 2. 到php目录 http://blog.aboutc.net/linux/65/co ...