需求:

基于上一道题,我想将结果按照总流量的大小由大到小输出。

思考:

默认mapreduce是对key字符串按照字母进行排序的,而我们想任意排序,只需要把key设成一个类,再对该类写一个compareTo(大于要比较对象返回1,等于返回0,小于返回-1)方法就可以了。

注:这里如果是实现java.lang.Comparable接口,最终报错,还是直接实现WritableComparable吧。

FlowBean.java更改如下:

package cn.darrenchan.hadoop.mr.flow;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException; import org.apache.hadoop.io.Writable;
import org.apache.hadoop.io.WritableComparable; public class FlowBean implements WritableComparable<FlowBean> {
private String phoneNum;// 手机号
private long upFlow;// 上行流量
private long downFlow;// 下行流量
private long sumFlow;// 总流量 public FlowBean() {
super();
} public FlowBean(String phoneNum, long upFlow, long downFlow) {
super();
this.phoneNum = phoneNum;
this.upFlow = upFlow;
this.downFlow = downFlow;
this.sumFlow = upFlow + downFlow;
} public String getPhoneNum() {
return phoneNum;
} public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
} 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 String toString() {
return upFlow + "\t" + downFlow + "\t" + sumFlow;
} // 从数据流中反序列出对象的数据
// 从数据流中读出对象字段时,必须跟序列化时的顺序保持一致
@Override
public void readFields(DataInput in) throws IOException {
phoneNum = in.readUTF();
upFlow = in.readLong();
downFlow = in.readLong();
sumFlow = in.readLong();
} // 将对象数据序列化到流中
@Override
public void write(DataOutput out) throws IOException {
out.writeUTF(phoneNum);
out.writeLong(upFlow);
out.writeLong(downFlow);
out.writeLong(sumFlow);
} @Override
public int compareTo(FlowBean flowBean) {
return sumFlow > flowBean.getSumFlow() ? -1 : 1;
} }

建立文件SortMR.java:

package cn.darrenchan.hadoop.mr.flowsort;

import java.io.IOException;

import org.apache.commons.io.output.NullWriter;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
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; import cn.darrenchan.hadoop.mr.flow.FlowBean; //执行命令:hadoop jar flowsort.jar cn.darrenchan.hadoop.mr.flowsort.SortMR /flow/output /flow/outputsort
public class SortMR {
public static class SortMapper extends
Mapper<LongWritable, Text, FlowBean, NullWritable> {
// 拿到一行数据,切分出各字段,封装为一个flowbean,作为key输出
@Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
String line = value.toString();
String[] words = StringUtils.split(line, "\t"); String phoneNum = words[0];
long upFlow = Long.parseLong(words[1]);
long downFlow = Long.parseLong(words[2]); context.write(new FlowBean(phoneNum, upFlow, downFlow),
NullWritable.get());
}
} public static class SortReducer extends
Reducer<FlowBean, NullWritable, Text, FlowBean> {
@Override
protected void reduce(FlowBean key, Iterable<NullWritable> values,
Context context) throws IOException, InterruptedException {
String phoneNum = key.getPhoneNum();
context.write(new Text(phoneNum), key);
}
} public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf); job.setJarByClass(SortMR.class); job.setMapperClass(SortMapper.class);
job.setReducerClass(SortReducer.class); job.setOutputKeyClass(Text.class);
job.setOutputValueClass(FlowBean.class); job.setMapOutputKeyClass(FlowBean.class);
job.setMapOutputValueClass(NullWritable.class); FileInputFormat.setInputPaths(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1])); System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}

我们现在处理的结果是上一次实验的输出结果,打成jar包flowsort.jar,执行命令:

hadoop jar flowsort.jar cn.darrenchan.hadoop.mr.flowsort.SortMR /flow/output /flow/outputsort

得到的处理信息如下:

17/02/26 05:22:36 INFO client.RMProxy: Connecting to ResourceManager at weekend110/192.168.230.134:8032
17/02/26 05:22:36 WARN mapreduce.JobSubmitter: Hadoop command-line option parsing not performed. Implement the Tool interface and execute your application with ToolRunner to remedy this.
17/02/26 05:22:36 INFO input.FileInputFormat: Total input paths to process : 1
17/02/26 05:22:36 INFO mapreduce.JobSubmitter: number of splits:1
17/02/26 05:22:37 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1488112052214_0003
17/02/26 05:22:37 INFO impl.YarnClientImpl: Submitted application application_1488112052214_0003
17/02/26 05:22:37 INFO mapreduce.Job: The url to track the job: http://weekend110:8088/proxy/application_1488112052214_0003/
17/02/26 05:22:37 INFO mapreduce.Job: Running job: job_1488112052214_0003
17/02/26 05:24:16 INFO mapreduce.Job: Job job_1488112052214_0003 running in uber mode : false
17/02/26 05:24:16 INFO mapreduce.Job: map 0% reduce 0%
17/02/26 05:24:22 INFO mapreduce.Job: map 100% reduce 0%
17/02/26 05:24:28 INFO mapreduce.Job: map 100% reduce 100%
17/02/26 05:24:28 INFO mapreduce.Job: Job job_1488112052214_0003 completed successfully
17/02/26 05:24:28 INFO mapreduce.Job: Counters: 49
File System Counters
FILE: Number of bytes read=933
FILE: Number of bytes written=187799
FILE: Number of read operations=0
FILE: Number of large read operations=0
FILE: Number of write operations=0
HDFS: Number of bytes read=735
HDFS: Number of bytes written=623
HDFS: Number of read operations=6
HDFS: Number of large read operations=0
HDFS: Number of write operations=2
Job Counters 
Launched map tasks=1
Launched reduce tasks=1
Data-local map tasks=1
Total time spent by all maps in occupied slots (ms)=3077
Total time spent by all reduces in occupied slots (ms)=2350
Total time spent by all map tasks (ms)=3077
Total time spent by all reduce tasks (ms)=2350
Total vcore-seconds taken by all map tasks=3077
Total vcore-seconds taken by all reduce tasks=2350
Total megabyte-seconds taken by all map tasks=3150848
Total megabyte-seconds taken by all reduce tasks=2406400
Map-Reduce Framework
Map input records=22
Map output records=22
Map output bytes=883
Map output materialized bytes=933
Input split bytes=112
Combine input records=0
Combine output records=0
Reduce input groups=22
Reduce shuffle bytes=933
Reduce input records=22
Reduce output records=22
Spilled Records=44
Shuffled Maps =1
Failed Shuffles=0
Merged Map outputs=1
GC time elapsed (ms)=142
CPU time spent (ms)=1280
Physical memory (bytes) snapshot=218406912
Virtual memory (bytes) snapshot=726446080
Total committed heap usage (bytes)=137433088
Shuffle Errors
BAD_ID=0
CONNECTION=0
IO_ERROR=0
WRONG_LENGTH=0
WRONG_MAP=0
WRONG_REDUCE=0
File Input Format Counters 
Bytes Read=623
File Output Format Counters 
Bytes Written=623

最终结果如下,可以看到是排序好的。

1363157985069 186852 200 187052
1363157985066 2481 24681 27162
1363157990043 63 11058 11121
1363157986072 18 9531 9549
1363157982040 102 7335 7437
1363157984041 9 6960 6969
1363157995093 3008 3720 6728
1363157995074 4116 1432 5548
1363157992093 4938 200 5138
1363157973098 27 3659 3686
1363157995033 20 3156 3176
1363157984040 12 1938 1950
1363157986029 3 1938 1941
1363157991076 1512 200 1712
1363157993044 12 1527 1539
1363157993055 954 200 1154
1363157985079 180 200 380
1363157986041 180 200 380
1363157988072 120 200 320
1363154400022 0 200 200
1363157983019 0 200 200
1363157995052 0 200 200

MapReduce实战(二)自定义类型排序的更多相关文章

  1. [c#基础]泛型集合的自定义类型排序

    引用 最近总有种感觉,自己复习的进度总被项目中的问题给耽搁了,项目中遇到的问题,不总结又不行,只能将复习基础方面的东西放后再放后.一直没研究过太深奥的东西,过去一年一直在基础上打转,写代码,反编译,不 ...

  2. C# 泛型集合的自定义类型排序

    一.泛型集合List<T>排序 经sort方法之后,采用了升序的方式进行排列的. List<int> list = new List<int>() { 2, 4, ...

  3. MapReduce实战:自定义输入格式实现成绩管理

    1. 项目需求 我们取有一份学生五门课程的期末考试成绩数据,现在我们希望统计每个学生的总成绩和平均成绩. 样本数据如下所示,每行数据的数据格式为:学号.姓名.语文成绩.数学成绩.英语成绩.物理成绩.化 ...

  4. java利用自定义类型对树形数据类型进行排序

    前言 为什么集合在存自定义类型时需要重写equals和hashCode? 1.先说List集合 List集合在存数据时是可以重复的但是 当我们需要判断一个对象是否在集合中存在时这样就有问题了! 因为我 ...

  5. golang 自定义类型的排序sort

    sort包中提供了很多排序算法,对自定义类型进行排序时,只需要实现sort的Interface即可,包括: func Len() int {... } func Swap(i, j int) {... ...

  6. Struts(二十):自定义类型转换器

    如何自定义类型转换器: 1)为什么需要自定义类型转化器?strtuts2不能自动完成字符串到所有的类型: 2) 如何定义类型转化器? 步骤一:创建自定义类型转化器的类,并继承org.apache.st ...

  7. 《SpringMVC从入门到放肆》十二、SpringMVC自定义类型转换器

    之前的教程,我们都已经学会了如何使用Spring MVC来进行开发,掌握了基本的开发方法,返回不同类型的结果也有了一定的了解,包括返回ModelAndView.返回List.Map等等,这里就包含了传 ...

  8. java编程排序之自定义类型的集合,按业务需求排序

    自定义引用类型放入集合中,按实际业务需求进行排序的两种思路 第一种思路: (1)自定义实体类实现java.lang.Comparable接口,重写public int compareTo(Object ...

  9. [Java]如何为一个自定义类型的List排序。

    好吧,三年了,又重拾我的博客了,是因为啥呢,哈哈哈.今天被问到一个题目,当场答不出来,动手动的少了,再此记录下来. Q:有一个MyObject类型的List,MyObject定义如下: class M ...

随机推荐

  1. c#跟objective-c语言特性的对比

    拿c#语言跟objective-c做个对比,记录下自己认为是差不多的东西. 学过objc的人相信对category这个东西肯定不陌生,它可以让我们在没有源码的基础上对原先的类添加额外的一些方法,写到这 ...

  2. [Algorithm] Fibonacci problem by using Dynamic programming

    vThere are three ways to solve Fibonacci problem Recursion Memoize Bottom-up 'First Recursion approa ...

  3. Office WPS如何让页与页之间不相互影响

    在一个页面结束的位置点击插入-分页符,完了之后测试按回车下一页的内容有没有跟着往下跑,如果还是跟着往下跑的,再插入一次分页符,一般插入多次之后就不会跟着跑了,但是插的太多会有空白页面   测试按回车, ...

  4. jQuery EasyUI API 中文文档 - 表单(form补充)

    继承(表单验证) 第一个参数如果是true那么就算key相同也会接着追加,相反怎会覆盖 $.extend([bool],obj,obj1); var obj = {name:"zhangsa ...

  5. 安装Vagrant出错 安装Homestead出错失败

    安装Vagrant出错 安装Homestead出错     我们也可以在电脑上创建其它文件夹,只需保证创建的文件夹路径跟 Homestead.yaml 文件中的 folders - map 保持一致即 ...

  6. [IOS A] - 一些开源类库

    因 为iOS SDK相对比较底层,所以开发者就得受累多做一些体力活.不过幸运的是,有很多第三方的类库可以用来简化很多不必要的工作.笔者整理了一下在本人学习过程 中用到的一些比较有用Objective- ...

  7. cocos2dx 制作单机麻将(四)

    cocos2dx 制作单机麻将(四) 麻将逻辑5.模拟出牌 // // main.cpp // MajiangLogicTest // // Created by TinyUlt on 14-8-16 ...

  8. PHP中文乱码的常见解决方法总结

    PHP中文乱码是PHP开发中的常见问题之一.PHP中文乱码有时发生在网页本身,有些产生在于MySQL交互的过程中,有时与操作系统有关.下面进行一番总结. 一.首先是PHP网页的编码 1. php文件本 ...

  9. 使用Openssl创建证书

    概述 SSL证书通过在客户端浏览器和Web服务器之间建立一条SSL安全通道(Secure socketlayer(SSL),SSL安全协议主要用来提供对用户和服务器的认证:对传送的数据进行加密和隐藏: ...

  10. Git使用总结 Asp.net生命周期与Http协议 托管代码与非托管代码的区别 通过IEnumerable接口遍历数据 依赖注入与控制反转 C#多线程——优先级 AutoFac容器初步 C#特性详解 C#特性详解 WPF 可触摸移动的ScrollViewer控件 .NET(C#)能开发出什么样的APP?盘点那些通过Smobiler开发的移动应用

    一,原理 首先,我们要明白Git是什么,它是一个管理工具或软件,用来管理什么的呢?当然是在软件开发过程中管理软件或者文件的不同版本的工具,一些作家也可以用这个管理自己创作的文本文件,由Linus开发的 ...