Hadoop日记Day13---使用hadoop自定义类型处理手机上网日志

时间:2022-03-06 23:58:38

测试数据的下载地址为:http://pan.baidu.com/s/1gdgSn6r


一、文件分析

  首先可以用文本编辑器打开一个HTTP_20130313143750.dat的二进制文件,这个文件的内容是我们的手机日志,文件的内容已经经过了优化,格式比较规整,便于学习研究,感兴趣的读者可以尝试一下。

  我从中截取文件中的一行记录内容进行分析:

1363157985066     13726230503    00-FD-07-A4-72-B8:CMCC    120.196.100.82    i02.c.aliimg.com

2     4    27    2 481    24681    200

  该日志文件的每个记录,一共有11个字段每个字段的含义如下图1.1所示。

Hadoop日记Day13---使用hadoop自定义类型处理手机上网日志

图 1.1

二、思路分析

  我们要统计这个文件中,同一手机号的流量汇总。而我们可以从图1.1中发现,记录中有四个字段以不同的形式表示手机的流量,这时你会想到什么呢?-----那就是面向对象的概念,我们可以自定义一个类来代表一个自定义类型去包含这几个值,用类中的属性,来表示这几个字段,来方面我们对数据的操作。

  现在我们按照MapReduce的分布式计算模型,分析一下如何实现我们的任务。首先我们有未经过处理的原始文件(相当于<k1,v1>),这个文件里存储着我需要的数据就是,那就是一个手机的流量的汇总数据(相当于<k3,v3>),而要从原始数据获得我们最终想要的数据,这中间需要经过一个过程,对原始数据进行初步加工处理,形成中间结果(相当于<k2,V2>),而<K2,V2>这时候代表什么呢?不难看出,将所有的原始数据经过map()函数的分组排序处理后,得到一个中间结果,这个中间结果是一个键值对<K2,V2>,而这里的K2应该就是电话号码,V2就是我们的自定义类型表示手机流量,最后将中间数据经过reduce()函数的归一化处理,得到我们的最终结果。

三、编程实现

1. 代码如下

 package mapreduce;

 import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable;
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.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.mapreduce.lib.partition.HashPartitioner; public class KpiApp {
static final String INPUT_PATH = "hdfs://hadoop:9000/wlan";
static final String OUT_PATH = "hdfs://hadoop:9000/out";
public static void main(String[] args) throws Exception{
final Job job = new Job(new Configuration(), KpiApp.class.getSimpleName()); FileInputFormat.setInputPaths(job, INPUT_PATH);//1.1 指定输入文件路径 job.setInputFormatClass(TextInputFormat.class);//指定哪个类用来格式化输入文件 job.setMapperClass(MyMapper.class);//1.2指定自定义的Mapper类 job.setMapOutputKeyClass(Text.class);//指定输出<k2,v2>的类型
job.setMapOutputValueClass(KpiWritable.class); job.setPartitionerClass(HashPartitioner.class);//1.3 指定分区类
job.setNumReduceTasks(1); //1.4 TODO 排序、分区 //1.5 TODO (可选)合并 job.setReducerClass(MyReducer.class);//2.2 指定自定义的reduce类 job.setOutputKeyClass(Text.class);//指定输出<k3,v3>的类型
job.setOutputValueClass(KpiWritable.class); FileOutputFormat.setOutputPath(job, new Path(OUT_PATH));//2.3 指定输出到哪里 job.setOutputFormatClass(TextOutputFormat.class);//设定输出文件的格式化类 job.waitForCompletion(true);//把代码提交给JobTracker执行
} static class MyMapper extends Mapper<LongWritable, Text, Text, KpiWritable>{
protected void map(LongWritable key, Text value, org.apache.hadoop.mapreduce.Mapper<LongWritable,Text,Text,KpiWritable>.Context context) throws IOException ,InterruptedException {
final String[] splited = value.toString().split("\t");
final String msisdn = splited[1];
final Text k2 = new Text(msisdn);
final KpiWritable v2 = new KpiWritable(splited[6],splited[7],splited[8],splited[9]);
context.write(k2, v2);
};
} static class MyReducer extends Reducer<Text, KpiWritable, Text, KpiWritable>{
/**
* @param k2 表示整个文件中不同的手机号码
* @param v2s 表示该手机号在不同时段的流量的集合
*/
protected void reduce(Text k2, java.lang.Iterable<KpiWritable> v2s, org.apache.hadoop.mapreduce.Reducer<Text,KpiWritable,Text,KpiWritable>.Context context) throws IOException ,InterruptedException {
long upPackNum = 0L;
long downPackNum = 0L;
long upPayLoad = 0L;
long downPayLoad = 0L; for (KpiWritable kpiWritable : v2s) {
upPackNum += kpiWritable.upPackNum;
downPackNum += kpiWritable.downPackNum;
upPayLoad += kpiWritable.upPayLoad;
downPayLoad += kpiWritable.downPayLoad;
} final KpiWritable v3 = new KpiWritable(upPackNum+"", downPackNum+"", upPayLoad+"", downPayLoad+"");
context.write(k2, v3);
};
}
} class KpiWritable implements Writable{
long upPackNum;
long downPackNum;
long upPayLoad;
long downPayLoad; public KpiWritable(){} public KpiWritable(String upPackNum, String downPackNum, String upPayLoad, String downPayLoad){
this.upPackNum = Long.parseLong(upPackNum);
this.downPackNum = Long.parseLong(downPackNum);
this.upPayLoad = Long.parseLong(upPayLoad);
this.downPayLoad = Long.parseLong(downPayLoad);
} @Override
public void readFields(DataInput in) throws IOException {
this.upPackNum = in.readLong();
this.downPackNum = in.readLong();
this.upPayLoad = in.readLong();
this.downPayLoad = in.readLong();
} @Override
public void write(DataOutput out) throws IOException {
out.writeLong(upPackNum);
out.writeLong(downPackNum);
out.writeLong(upPayLoad);
out.writeLong(downPayLoad);
} @Override
public String toString() {
return upPackNum + "\t" + downPackNum + "\t" + upPayLoad + "\t" + downPayLoad;
}
}

2 .运行结果如下

aaarticlea/png;base64,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" alt="" />

图 3.1

Hadoop日记Day13---使用hadoop自定义类型处理手机上网日志的更多相关文章

  1. Hadoop学习笔记—5&period;自定义类型处理手机上网日志

    转载自http://www.cnblogs.com/edisonchou/p/4288737.html Hadoop学习笔记—5.自定义类型处理手机上网日志 一.测试数据:手机上网日志 1.1 关于这 ...

  2. Hadoop自定义类型处理手机上网日志

    job提交源码分析 在eclipse中的写的代码如何提交作业到JobTracker中的哪?(1)在eclipse中调用的job.waitForCompletion(true)实际上执行如下方法 con ...

  3. Hadoop日记系列目录

    下面是Hadoop日记系列的目录,由于目前时间不是很充裕,以后的更新的速度会变慢,会按照一星期发布一期的原则进行,希望能和大家相互学习.交流. 目录安排 1>  Hadoop日记Day1---H ...

  4. Hadoop日记Day18---MapReduce排序分组

    本节所用到的数据下载地址为:http://pan.baidu.com/s/1bnfELmZ MapReduce的排序分组任务与要求 我们知道排序分组是MapReduce中Mapper端的第四步,其中分 ...

  5. Hadoop日记Day17---计数器、map规约、分区学习

    一.Hadoop计数器 1.1 什么是Hadoop计数器 Haoop是处理大数据的,不适合处理小数据,有些大数据问题是小数据程序是处理不了的,他是一个高延迟的任务,有时处理一个大数据需要花费好几个小时 ...

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

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

  7. Hadoop日记Day15---MapReduce新旧api的比较

    我使用hadoop的是hadoop1.1.2,而很多公司也在使用hadoop0.2x版本,因此市面上的hadoop资料版本不一,为了扩充自己的知识面,MapReduce的新旧api进行了比较研究. h ...

  8. Hadoop生态圈-Azkaban实战之Command类型执行指定脚本

    Hadoop生态圈-Azkaban实战之Command类型执行指定脚本 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 1>.服务端测试代码(别忘记添加权限哟!) [yinzh ...

  9. Hadoop(七):自定义输入输出格式

    MR输入格式概述 数据输入格式 InputFormat. 用于描述MR作业的数据输入规范. 输入格式在MR框架中的作用: 文件进行分块(split),1个块就是1个Mapper任务. 从输入分块中将数 ...

随机推荐

  1. 安装shopex注意事项

    [原创]关于PHP5.3.x和Zend Optimizer(Zend Guard Loader),以及shopex4.8.5安装的问题  http://dzmailbox.blog.163.com/b ...

  2. Debian 7 安装使用 Virtualbox及增强功能

    一.安装virtualbox 可以从源里安装 sudo apt-get install virtualbox 也可以下载最新版安装 https://www.virtualbox.org/wiki/Do ...

  3. Mac&amp&semi;iOS Socket

    链接地址:http://geeklu.com/2012/01/macios-socket/ Geeklu 登录 1 Recommend 7 分享 按评分高低排序   加入讨论...         振 ...

  4. python教程6-2:字符串标识符

    标识符合法性检查. 1.字母或者下划线开始. 2.后面是字母.下划线或者数字. 3.检查长度大于等于1. 4.可以识别关键字. python35 idcheck.py  idcheck.py impo ...

  5. 关于Android中so解析那些事

    1.Android系统目前支持的CPU架构:ARMv5.ARMv7.x86.MIPS.ARMv8.MIPS64.x86_64,每一种都关联着一个ABI(Application Binary Inter ...

  6. SpriteBuilder中如何平均拉伸精灵帧动画的距离

    首先要在Timeline中选中所有的精灵帧,可以通过如下2种的任意一种办法达成: 1按下Shift键的同时鼠标单击它们 2鼠标在Timeline空白区拖拽直到拉出的矩形包围住所有精灵帧方块后放开鼠标. ...

  7. hadoop old API CombineFileInputFormat

    来自:http://f.dataguru.cn/thread-271645-1-1.html 简介 本文主要介绍下面4个方面 1.为什么要使用CombineFileInputFormat 2.Comb ...

  8. 解压命令tar zxvf中zxvf的意思

    x : 从 tar 包中把文件提取出来 z : 表示 tar 包是被 gzip 压缩过的,所以解压时需要用 gunzip 解压 v : 显示详细信息 f xxx.tar.gz : 指定被处理的文件是 ...

  9. zepto&period;js 实现原理解析

    zepto 是移动端常用的 dom 库,代码轻巧,操作方式类同 jquery.那么 zepto 的核心实现原理是什么呢?

  10. django -- url 的 命名空间

    命名空间 a. project.urls.py 1 2 3 4 5 6 from django.conf.urls import url,include   urlpatterns = [     u ...