一、背景

1.1 流程

  实现排序,分组拍上一篇通过Partitioner实现了。

  实现接口,自动产生接口方法,写属性,产生getter和setter,序列化和反序列化属性,写比较方法,重写toString,为了方便复制写够着方法,不过重写够着方法map里需要不停地new,发现LongWritable有set方法,text也有,可以用,产生默认够着方法。

	public void set(String account,double income,double expense,double surplus) {
this.account = account;
this.income = income;
this.expense = expense;
this.surplus = income-expense;
}

1.2 数据集

为了和上一篇保在知识上持递进,数据及换了,名字没变。

  下面是输出结果,其实mr也会自动排序,不过string按字典序排序了。

二、理论知识

  字符串拼接,记得以前自己写过,现在拿出来看看,http://www.cnblogs.com/hxsyl/archive/2012/10/18/2729112.html

  简单总结扩展如下:String是final的,不能改变也不能继承,因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。

 

  如果for循环1w次,这句 string += "hello";的过程相当于将原有的string变量指向的对象内容取出与"hello"作字符串相加操作再存进另一个新的String对象当中,再让string变量指向新生成的对象。反编译出的字节码文件可以很清楚地看出,每次循环会new出一个StringBuilder对象,然后进行append操作,最后通过toString方法返回String对象。也就是说这个循环执行完毕new出了10000个对象,试想一下,如果这些对象没有被回收,内存浪费不说,有可能重复使用赵成系统卡死。从上面还可以看出:string+="hello"的操作事实上会自动被JVM优化成:

  StringBuilder str = new StringBuilder(string);

  str.append("hello");

  str.toString();

  如果直接for循环里StringBuilder 的话会只是new一次。效率高。

  而StringBuffer是线程安全的,多了synchronized关键字,也就是在多线程下会顺序读取换冲刺。

 参考了这个http://blog.csdn.net/loveyaozu/article/details/47037957

三、实体类

  收入相同的话按消费从低到高,否则收入从高到低。

package cn.app.hadoop.mr.sort;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.math.BigDecimal; import org.apache.hadoop.io.WritableComparable;
import org.apache.jasper.tagplugins.jstl.core.Out; //Writable是序列化接口
//泛型是InfoBean,就像比较学生信息一样,成绩,性别等 ,封装在了一个bean里
//不过发现WritableComparable 有了序列化和反序列化
public class InfoBean implements WritableComparable<InfoBean>{ private String account;
//金钱类都需要BigDecimal,double顺势精度,不过不知道下边序列化咋写类型,所以先用double,估计writeUTF可以
private double income;
private double expense;
private double surplus; public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public double getIncome() {
return income;
}
public void setIncome(double income) {
this.income = income;
}
public double getExpense() {
return expense;
}
public void setExpense(double expense) {
this.expense = expense;
}
public double getSurplus() {
return surplus;
}
public void setSurplus(double surplus) {
this.surplus = surplus;
}
public void readFields(DataInput in) throws IOException {
// TODO Auto-generated method stub
this.account = in.readUTF();
this.income = in.readDouble();
this.expense = in.readDouble();
this.surplus = in.readDouble();
}
public void write(DataOutput out) throws IOException {
// TODO Auto-generated method stub
out.writeUTF(account);
out.writeDouble(income);
out.writeDouble(expense);
out.writeDouble(surplus); } public void set(String account,double income,double expense) {
this.account = account;
this.income = income;
this.expense = expense;
this.surplus = income - expense;
} public InfoBean() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "InfoBean [income=" + income + ", expense=" + expense
+ ", surplus=" + surplus + "]";
}
public int compareTo(InfoBean o) {
// TODO Auto-generated method stub
if(this.income == o.getIncome()) {
return this.expense>o.getExpense()?1:-1;
}else {
return this.income>o.getIncome()?-1:1;
}
}
}

四、第一种实现

4.1 Mapper

//第一个处理文本的话一般是LongWritable  或者object
//一行一行的文本是text
//输出的key的手机号 定位Text
//结果是DataBean 一定要实现Writable接口
public class InfoSortMapper extends Mapper<LongWritable, Text, Text, InfoBean> { private InfoBean v = new InfoBean();
private Text k = new Text(); public void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
String line = value.toString();
String[] fields = line.split("\t");
String account = fields[0];
double in = Double.parseDouble(fields[1]);
double out = Double.parseDouble(fields[2]); //不用每次new 几遍不重写内存引用,也很站用资源
k.set(account);
v.set(account, in, out); context.write(k, v);
}

  4.2 Reducer

public class InfoSortReducer extends Reducer<Text, InfoBean, Text, InfoBean> {

	//k就是key,不需要
private InfoBean v = new InfoBean();
public void reduce(Text key, Iterable<InfoBean> value, Context context)
throws IOException, InterruptedException {
// process values
double incomeSum = 0;
double expenseSum = 0;
for (InfoBean o : value) {
incomeSum += o.getIncome();
expenseSum += o.getExpense();
}
v.set(key.toString(), incomeSum, expenseSum);
//databean会自动调用toString
context.write(key,v);
}
}

五、第二种实现

5.1 Mapper

//对 InfoBean  排序  k2就是他
public class SortMapper extends Mapper<LongWritable, Text, InfoBean, NullWritable> { private InfoBean k = new InfoBean();
public void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
String line = value.toString();
String[] fields = line.split("\t");
String account = fields[0];
double in = Double.parseDouble(fields[1]);
double out = Double.parseDouble(fields[2]); //不用每次new 几遍不重写内存引用,也很站用资源
k.set(account, in, out);
//value必须是NullWritable.get(),NullWritable不行,提示不是变量
context.write(k, NullWritable.get());
}
}

  5.2 Reducer

//对 InfoBean  排序  k2就是他
public class SortMapper extends Mapper<LongWritable, Text, InfoBean, NullWritable> { private InfoBean k = new InfoBean();
public void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
String line = value.toString();
String[] fields = line.split("\t");
String account = fields[0];
double in = Double.parseDouble(fields[1]);
double out = Double.parseDouble(fields[2]); //不用每次new 几遍不重写内存引用,也很站用资源
k.set(account, in, out);
//value必须是NullWritable.get(),NullWritable不行,提示不是变量
context.write(k, NullWritable.get());
}
}

六、结束语

  如果k2 v2和k4 v4,也就是mapp的输出和reducer的输出类型不一致的话必须在Main里也设置Mapper的输出,上面的第二种就是。

job.setMapOutputKeyClass(InfoBean.class);
job.setMapOutputValueClass(NullWritable.class); job.setOutputKeyClass(Text.class);
job.setOutputValueClass(InfoBean.class);

  否则java里不报错,加上log4j后看到类型不匹配。

MapReduce实现手机上网日志分析(排序)的更多相关文章

  1. MapReduce实现手机上网日志分析(分区)

    一.问题背景 实际业务的需要,比如以移动为例,河南的用户去了北京上网,那么他的上网信息默认保存在了北京的基站,那么我们想要查询北京地区的上网日志信息默认也包含了其他地区用户的在本区的上网信息,否则只能 ...

  2. MapReduce实现手机上网流量分析(业务逻辑)

    一.问题背景 现在的移动刚一通话就可以在网站上看自己的通话记录,以前是本月只能看上一个月.不过流量仍然是只能看上一月的. 目的就是找到用户在一段时间内的上网流量. 本文并没有对时间分组.下一节进行分区 ...

  3. 使用Pig对手机上网日志进行分析

    在安装成功Pig的基础上.本文将使用Pig对手机上网日志进行分析,详细过程例如以下: 写在前面: 手机上网日志文件phone_log.txt.文件内容 及 字段说明部分截图例如以下 需求分析 显示每一 ...

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

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

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

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

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

    测试数据的下载地址为:http://pan.baidu.com/s/1gdgSn6r 一.文件分析 首先可以用文本编辑器打开一个HTTP_20130313143750.dat的二进制文件,这个文件的内 ...

  7. Hadoop学习笔记—20.网站日志分析项目案例(一)项目介绍

    网站日志分析项目案例(一)项目介绍:当前页面 网站日志分析项目案例(二)数据清洗:http://www.cnblogs.com/edisonchou/p/4458219.html 网站日志分析项目案例 ...

  8. ELK日志分析平台环境部署 (yum安装)

    前言:通常体质被分散存储在不同的设备上面,在庞大的服务器集群中,我们需要集中化的管理,日志的统计和检索,一般我们使用grep和awk,wc等linux命令虽然能够实现检索和统计,但是呢,对于要求更高的 ...

  9. Hadoop学习笔记—20.网站日志分析项目案例

    1.1 项目来源 本次要实践的数据日志来源于国内某技术学习论坛,该论坛由某培训机构主办,汇聚了众多技术学习者,每天都有人发帖.回帖,如图1所示. 图1 项目来源网站-技术学习论坛 本次实践的目的就在于 ...

随机推荐

  1. Play Framework 完整实现一个APP(六)

    需要为Blog添加 查看和发表评论的功能 1.创建查看功能 Application.java中添加 show() 方法 public static void show(Long id) { Post ...

  2. 集合2--毕向东java基础教程视频学习笔记

    Day14 08 LinkedList09 LinkedList练习10 ArrayList练习11 ArrayList练习2 12 HashSet13 HashSet存储自定义对象14 HashSe ...

  3. Redhat Linux安装JDK 1.7

    本篇主要介绍在Redhat Linux(Red Hat Enterprise Linux Server release 5.7 (Tikanga))系统上安装JDK 1.7,其它Linux平台安装也大 ...

  4. 如何转换SQL Server 2008数据库到SQL Server 2005

        背景介绍: 公司一套系统使用的是SQL SERVER 2008数据库,突然一天收到邮件,需要将这套系统部署到各个不同地方(海外)的工厂,需要在各个工厂部署该数据库,等我将准备工作做好,整理文档 ...

  5. 0024 Java学习笔记-面向对象-包装类、对象的比较、String常量池问题

    包装类 基本类型-->包装类 byte-->Byte short-->Short int-->Integer long-->Long char-->Characte ...

  6. redis 集群配置实战

    文章转载自:http://hot66hot.iteye.com/blog/2050676 最近研究Redis-cluster,正好搭建了一个环境,遇到了很多坑,系统的总结下,等到redis3 rele ...

  7. W3School-CSS 外边距 (margin) 实例

    CSS 外边距 (margin) 实例 CSS 实例 CSS 背景实例 CSS 文本实例 CSS 字体(font)实例 CSS 边框(border)实例 CSS 外边距 (margin) 实例 CSS ...

  8. Form 引用方法库

    进入注册表,win+R 输入:regedit,找到HKEY_LOCAL_MACHINE->SOFTWARE->ORACLE ,在右侧找到:FORMS60_PATH,双击,把方法库的路径以英 ...

  9. git 中关于LF 和 CRLF 的问题

    git 中关于LF 和 CRLF 的转换问题注意: Windows下编辑器设置中,建议调整设置为Unix风格.(具体设置位置各种编辑器上不同,需要找找) 使用Git Bash进行命令行操作时,运行一下 ...

  10. 迅为最新推出iTOP-6818开发平台无缝支持4418开发板

    iTOP-6818开发板是一款四核ARM 八核开发板与iTOP-4418开发板完全兼容,CPU主频1.4GHz,内存1GB DDR3(2GB可选),存储16GB EMMC,板载千兆以太网,GPS,WI ...