本文以手机流量统计为例:

日志中包含下面字段

现在需要统计手机的上行数据包,下行数据包,上行总流量,下行总流量。

分析:可以以手机号为key 以上4个字段为value传传递数据。

这样则需要自己定义一个数据类型,用于封装要统计的4个字段,在map 与reduce之间传递和shuffle

注:作为key的自定义类型需要实现WritableComparable 里面的compareTo方法

作为value的自定义类 则只需实现Writable里面的方法

自定义代码如下:

package org.apache.hadoop.mapreduce.io;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException; import org.apache.hadoop.io.Writable; /***
* customize mobile data writable
* @author nele
*
*/
public class MobileDataWritable implements
Writable { private long upPackNum; private long downPackNum; private long upPayLoad; private long downPayLoad; public long getUpPackNum() {
return upPackNum;
} public void setUpPackNum(long upPackNum) {
this.upPackNum = upPackNum;
} public long getDownPackNum() {
return downPackNum;
} public void setDownPackNum(long downPackNum) {
this.downPackNum = downPackNum;
} public long getUpPayLoad() {
return upPayLoad;
} public void setUpPayLoad(long upPayLoad) {
this.upPayLoad = upPayLoad;
} public long getDownPayLoad() {
return downPayLoad;
} public void setDownPayLoad(long downPayLoad) {
this.downPayLoad = downPayLoad;
} public MobileDataWritable() {
} public MobileDataWritable(long upPackNum, long downPackNum, long upPayLoad,
long downPayLoad) {
this.set(upPackNum, downPackNum, upPayLoad, downPayLoad);
} public void set(long upPackNum, long downPackNum, long upPayLoad,
long downPayLoad) {
this.upPackNum = upPackNum;
this.downPackNum = downPackNum;
this.upPayLoad = upPayLoad;
this.downPayLoad = downPayLoad;
} public void write(DataOutput out) throws IOException {
out.writeLong(upPackNum);
out.writeLong(downPackNum);
out.writeLong(upPayLoad);
out.writeLong(downPayLoad);
} 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 int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (downPackNum ^ (downPackNum >>> 32));
result = prime * result + (int) (downPayLoad ^ (downPayLoad >>> 32));
result = prime * result + (int) (upPackNum ^ (upPackNum >>> 32));
result = prime * result + (int) (upPayLoad ^ (upPayLoad >>> 32));
return result;
} @Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MobileDataWritable other = (MobileDataWritable) obj;
if (downPackNum != other.downPackNum)
return false;
if (downPayLoad != other.downPayLoad)
return false;
if (upPackNum != other.upPackNum)
return false;
if (upPayLoad != other.upPayLoad)
return false;
return true;
} @Override
public String toString() {
return upPackNum + "\t" +downPackNum+ "\t" + upPayLoad + "\t" + downPayLoad;
} }

现在就可以使用自定义的类型进行手机流量的统计 代码如下:

/***
* MapReduce Module
*
* @author nele
*
*/
public class MobileDataMapReduce extends Configured implements Tool { // map class
/**
*
* @author nele
*
*/
public static class MobileDataMapper extends
Mapper<LongWritable, Text, Text, MobileDataWritable> { public Text outPutKey = new Text();
public MobileDataWritable outPutValue = new MobileDataWritable(); @Override
public void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
System.out.println(key+":"+value);
String[] arr = value.toString().split("\t");
outPutKey.set(arr[1]);
outPutValue.set(Long.valueOf(arr[6]), Long.valueOf(arr[7]),
Long.valueOf(arr[8]), Long.valueOf(arr[9]));
context.write(outPutKey, outPutValue);
} } // reduce class
/***
*
* @author nele
*
*/
public static class MobileDataReducer extends
Reducer<Text, MobileDataWritable, Text, MobileDataWritable> { private Text outPutKey = new Text();
private MobileDataWritable outPutValue = new MobileDataWritable(); @Override
public void reduce(Text key, Iterable<MobileDataWritable> values,
Context context) throws IOException, InterruptedException {
long upPackNum = 0;
long downPackNum = 0;
long upPayLoad = 0;
long downPayLoad = 0;
for (MobileDataWritable val : values) {
upPackNum += val.getUpPackNum();
downPackNum += val.getDownPackNum();
upPayLoad += val.getUpPayLoad();
downPayLoad += val.getDownPayLoad();
}
outPutKey.set(key);
outPutValue.set(upPackNum, downPackNum, upPayLoad, downPayLoad);
context.write(outPutKey, outPutValue);
}
} // run method
public int run(String[] args) throws Exception {
Configuration conf = super.getConf(); // create job
Job job = Job.getInstance(conf, this.getClass().getSimpleName());
job.setJarByClass(this.getClass()); // set input path
Path inPath = new Path(args[0]);
FileInputFormat.addInputPath(job, inPath); // map
job.setMapperClass(MobileDataMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(MobileDataWritable.class); // conbile
job.setCombinerClass(MobileDataReducer.class); // reduce
job.setReducerClass(MobileDataReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(MobileDataWritable.class); // output
Path outPath = new Path(args[1]);
FileOutputFormat.setOutputPath(job, outPath); // submit
return job.waitForCompletion(true) ? 0 : 1;
} public static void main(String[] args) throws Exception {
args = new String[] {
"hdfs://bigdata5:8020/user/nele/data/input/HTTP_20130313143750.data",
"hdfs://bigdata5:8020/user/nele/data/output/output6" }; Configuration conf = new Configuration(); int status = ToolRunner.run(conf, new MobileDataMapReduce(), args); System.exit(status);
} }

这样就可以统计 给出的数据日志中的手机各种流量的数据

mapreduce 自定义数据类型的简单的应用的更多相关文章

  1. Hadoop MapReduce自定义数据类型

    一 自定义数据类型的实现 1.继承接口Writable,实现其方法write()和readFields(), 以便该数据能被序列化后完成网络传输或文件输入/输出: 2.如果该数据需要作为主键key使用 ...

  2. 自定义MapReduce中数据类型

    数据类型(都实现了Writable接口) BooleanWritable 布尔类型 ByteWritable 单字节数值 DoubleWritable 双字节数值 FloatWritable 浮点数 ...

  3. hadoop的自定义数据类型和与关系型数据库交互

    最近有一个需求就是在建模的时候,有少部分数据是postgres的,只能读取postgres里面的数据到hadoop里面进行建模测试,而不能导出数据到hdfs上去. 读取postgres里面的数据库有两 ...

  4. Hadoop mapreduce自定义分组RawComparator

    本文发表于本人博客. 今天接着上次[Hadoop mapreduce自定义排序WritableComparable]文章写,按照顺序那么这次应该是讲解自定义分组如何实现,关于操作顺序在这里不多说了,需 ...

  5. java基础(14):Eclipse、面向对象、自定义数据类型的使用

    1. Eclipse的应用 1. 常用快捷操作 Ctrl+T:查看所选中类的继承树 例如,在下面代码中,选中Teacher类名,然后按Ctrl+T,就会显示出Teacher类的继承关系 //员工 ab ...

  6. js数据类型很简单,却也不简单

    最近脑子里有冒出"多看点书"的想法,但我个人不是很喜欢翻阅纸质书籍,另一方面也是因为我能抽出来看书的时间比较琐碎,所以就干脆用app看电子书了(如果有比较完整的阅读时间,还是建议看 ...

  7. TVM自定义数据类型

    TVM自定义数据类型 本文将介绍"自定义数据类型"框架,该框架可在TVM中使用自定义数据类型. 介绍 在设计加速器时,关键是如何近似地表示硬件中的实数.这个问题具有长期的行业标准解 ...

  8. 自主数据类型:在TVM中启用自定义数据类型探索

    自主数据类型:在TVM中启用自定义数据类型探索 介绍 在设计加速器时,一个重要的决定是如何在硬件中近似地表示实数.这个问题有一个长期的行业标准解决方案:IEEE 754浮点标准.1.然而,当试图通过构 ...

  9. 【填坑往事】使用Rxjava2的distinct操作符处理自定义数据类型去重的问题

    最近碰到一个问题,自定义数据类型列表中出现了重复数据,需要去重.处理去重的办法很多,比如借助Set集合类,使用双重循环拿每一个元素和其他元素对比等.这里介绍一种简单而且比较优雅的方式:使用Rxjava ...

随机推荐

  1. 【BZOJ-4631】踩气球 线段树 + STL

    4631: 踩气球 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 224  Solved: 114[Submit][Status][Discuss] ...

  2. VS2010 asp.net development server 无法展示svg图片

    无解!只能使用IIS Express或者部署到服务器上的IIS能解决! 以下为解释: http://stackoverflow.com/questions/5981309/asp-net-develo ...

  3. [NOIP2012] 提高组 洛谷P1079 Vigenère 密码

    题目描述 16 世纪法国外交家 Blaise de Vigenère 设计了一种多表密码加密算法――Vigenère 密 码.Vigenère 密码的加密解密算法简单易用,且破译难度比较高,曾在美国南 ...

  4. Apache Mod/Filter Development

    catalog . 引言 . windows下开发apache模块 . mod进阶: 接收客户端数据的 echo 模块 . mod进阶: 可配置的 echo 模块 . mod进阶: 过滤器 0. 引言 ...

  5. POJ 2484 A Funny Game(博弈论)

    题目链接: 传送门 A Funny Game Time Limit: 1000MS     Memory Limit: 10000K Description Alice and Bob decide ...

  6. POJ 2739 Sum of Consecutive Prime Numbers(尺取法)

    题目链接: 传送门 Sum of Consecutive Prime Numbers Time Limit: 1000MS     Memory Limit: 65536K Description S ...

  7. kali linux 2.0安装sublime text 2

    第一种方法:Download the Sublime Text 2 & Extract it:32位:$ wget http://c758482.r82.cf2.rackcdn.com/Sub ...

  8. java中的异常理解

    java异常是java提供的用于处理程序中错误的一种机制.所谓错误是指在程序运行的过程中发生的一些异常事件(如:除0溢出,数组下标越界,所要读取的文件不存在).设计良好地程序应该在程序异常发生时提供处 ...

  9. 会话控制:session与cookie

    我们在浏览网站时,访问的每一个web页面都需要使用"http协议"实现.而HTTP协议是无状态协议,就是说HTTP协议没有一个内建机制来维护两个事务之间的状态.当一个用户请求一个页 ...

  10. e_msg_c_as_register_req-注册存储过程

    TOP:BEGIN #Routine body goes here... IF EXISTS ( SELECT * FROM `global_account` WHERE `plantform_id` ...