不多说,直接上代码。

  对流量原始日志进行流量统计,将不同省份的用户统计结果输出到不同文件。

代码

package zhouls.bigdata.myMapReduce.flowsum;

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 phoneNB;
private long up_flow;
private long d_flow;
private long s_flow;

//在反序列化时,反射机制需要调用空参构造函数,所以显示定义了一个空参构造函数
public FlowBean(){}

//为了对象数据的初始化方便,加入一个带参的构造函数
public FlowBean(String phoneNB, long up_flow, long d_flow) {
this.phoneNB = phoneNB;
this.up_flow = up_flow;
this.d_flow = d_flow;
this.s_flow = up_flow + d_flow;
}

public String getPhoneNB() {
return phoneNB;
}

public void setPhoneNB(String phoneNB) {
this.phoneNB = phoneNB;
}

public long getUp_flow() {
return up_flow;
}

public void setUp_flow(long up_flow) {
this.up_flow = up_flow;
}

public long getD_flow() {
return d_flow;
}

public void setD_flow(long d_flow) {
this.d_flow = d_flow;
}

public long getS_flow() {
return s_flow;
}

public void setS_flow(long s_flow) {
this.s_flow = s_flow;
}

//将对象数据序列化到流中
public void write(DataOutput out) throws IOException {

out.writeUTF(phoneNB);
out.writeLong(up_flow);
out.writeLong(d_flow);
out.writeLong(s_flow);

}

//从数据流中反序列出对象的数据
//从数据流中读出对象字段时,必须跟序列化时的顺序保持一致
public void readFields(DataInput in) throws IOException {

phoneNB = in.readUTF();
up_flow = in.readLong();
d_flow = in.readLong();
s_flow = in.readLong();

}

@Override
public String toString() {

return "" + up_flow + "\t" +d_flow + "\t" + s_flow;
}

public int compareTo(FlowBean o) {
return s_flow>o.getS_flow()?-1:1;
}

}

package zhouls.bigdata.myMapReduce.flowsum;

import java.io.IOException;

import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

/**
* FlowBean 是我们自定义的一种数据类型,要在hadoop的各个节点之间传输,应该遵循hadoop的序列化机制
* 就必须实现hadoop相应的序列化接口
*
*
*/
public class FlowSumMapper extends Mapper<LongWritable, Text, Text, FlowBean>{

//拿到日志中的一行数据,切分各个字段,抽取出我们需要的字段:手机号,上行流量,下行流量,然后封装成kv发送出去
@Override
protected void map(LongWritable key, Text value,Context context)
throws IOException, InterruptedException {

//拿一行数据
String line = value.toString();
//切分成各个字段
String[] fields = StringUtils.split(line, "\t");

//拿到我们需要的字段
String phoneNB = fields[1];
long u_flow = Long.parseLong(fields[7]);
long d_flow = Long.parseLong(fields[8]);

//封装数据为kv并输出
context.write(new Text(phoneNB), new FlowBean(phoneNB,u_flow,d_flow));

}

}

package zhouls.bigdata.myMapReduce.flowsum;

import java.io.IOException;

import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

public class FlowSumReducer extends Reducer<Text, FlowBean, Text, FlowBean>{

//框架每传递一组数据<1387788654,{flowbean,flowbean,flowbean,flowbean.....}>调用一次我们的reduce方法
//reduce中的业务逻辑就是遍历values,然后进行累加求和再输出
@Override
protected void reduce(Text key, Iterable<FlowBean> values,Context context)
throws IOException, InterruptedException {

long up_flow_counter = 0;
long d_flow_counter = 0;

for(FlowBean bean : values){

up_flow_counter += bean.getUp_flow();
d_flow_counter += bean.getD_flow();

}

context.write(key, new FlowBean(key.toString(), up_flow_counter, d_flow_counter));

}

}

package zhouls.bigdata.myMapReduce.flowsum;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.InputFormat;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.OutputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

import zhouls.bigdata.myMapReduce.Anagram.Anagram;

//这是job描述和提交类的规范写法
public class FlowSumRunner extends Configured implements Tool{

public int run(String[] arg0) throws Exception {

Configuration conf = new Configuration();
Job job = Job.getInstance(conf);

job.setJarByClass(FlowSumRunner.class);

job.setMapperClass(FlowSumMapper.class);
job.setReducerClass(FlowSumReducer.class);

job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(FlowBean.class);

job.setOutputKeyClass(Text.class);
job.setOutputValueClass(FlowBean.class);

FileInputFormat.addInputPath(job, new Path(arg0[0]));// 文件输入路径
FileOutputFormat.setOutputPath(job, new Path(arg0[1]));// 文件输出路径
job.waitForCompletion(true);

return 0;
}

public static void main(String[] args) throws Exception {
//集群路径
// String[] args0 = { "hdfs://HadoopMaster:9000/flowSum/HTTP_20130313143750.dat",
// "hdfs://HadoopMaster:9000/out/flowSum"};

//本地路径
String[] args0 = { "./data/flowSum/HTTP_20130313143750.dat",
"./out/flowSum/"};

int ec = ToolRunner.run( new Configuration(), new FlowSumRunner(), args0);
System. exit(ec);
}

}

Hadoop MapReduce编程 API入门系列之网页流量版本1(二十二)的更多相关文章

  1. Hadoop MapReduce编程 API入门系列之网页流量版本1(二十一)

    不多说,直接上代码. 对流量原始日志进行流量统计,将不同省份的用户统计结果输出到不同文件. 代码 package zhouls.bigdata.myMapReduce.areapartition; i ...

  2. Hadoop MapReduce编程 API入门系列之压缩和计数器(三十)

    不多说,直接上代码. Hadoop MapReduce编程 API入门系列之小文件合并(二十九) 生成的结果,作为输入源. 代码 package zhouls.bigdata.myMapReduce. ...

  3. Hadoop MapReduce编程 API入门系列之网页排序(二十八)

    不多说,直接上代码. Map output bytes=247 Map output materialized bytes=275 Input split bytes=139 Combine inpu ...

  4. Hadoop MapReduce编程 API入门系列之挖掘气象数据版本3(九)

    不多说,直接上干货! 下面,是版本1. Hadoop MapReduce编程 API入门系列之挖掘气象数据版本1(一) 下面是版本2. Hadoop MapReduce编程 API入门系列之挖掘气象数 ...

  5. Hadoop MapReduce编程 API入门系列之挖掘气象数据版本2(十)

    下面,是版本1. Hadoop MapReduce编程 API入门系列之挖掘气象数据版本1(一) 这篇博文,包括了,实际生产开发非常重要的,单元测试和调试代码.这里不多赘述,直接送上代码. MRUni ...

  6. Hadoop MapReduce编程 API入门系列之join(二十六)(未完)

    不多说,直接上代码. 天气记录数据库 Station ID Timestamp Temperature 气象站数据库 Station ID Station Name 气象站和天气记录合并之后的示意图如 ...

  7. Hadoop MapReduce编程 API入门系列之MapReduce多种输入格式(十七)

    不多说,直接上代码. 代码 package zhouls.bigdata.myMapReduce.ScoreCount; import java.io.DataInput; import java.i ...

  8. Hadoop MapReduce编程 API入门系列之自定义多种输入格式数据类型和排序多种输出格式(十一)

    推荐 MapReduce分析明星微博数据 http://git.oschina.net/ljc520313/codeexample/tree/master/bigdata/hadoop/mapredu ...

  9. Hadoop MapReduce编程 API入门系列之wordcount版本1(五)

    这个很简单哈,编程的版本很多种. 代码版本1 package zhouls.bigdata.myMapReduce.wordcount5; import java.io.IOException; im ...

随机推荐

  1. 图像局部显著性—点特征(SiftGPU)

    SIFT的计算复杂度较高. SiftGpu的主页:SiftGPU: A GPU Implementation of ScaleInvariant Feature Transform (SIFT) 对S ...

  2. veket智能机器人

    官方网站:http://www.lucky8k.com/forum.php veket儿童操作系统 希望工具超过小puppy linux系统 一个还在发展中的linux系统: Slax Linux : ...

  3. AS3.0+PHP写入mySQL

    php中$_POST变量是一个数组,用于收集来自method="post"的值,内容是有HTTP POST方法发送的变量名称和值. 从带有POST方法的表单发送的信息,对任何人都是 ...

  4. HDU_1850_nim游戏

    Being a Good Boy in Spring Festival Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32 ...

  5. Cache-Control 机制是为浏览器定制的?

    Cache-Control 机制是为浏览器定制的?

  6. C#—接口和抽象类的区别?

    一.接口 接口是指对协定进行定义的引用类型,其他类型实现接口,以保证它们支持某些操作.接口指定必须由类提供的成员或实现它的其他接口.与类相似,接口可以包含方法.属性.索引器和事件作为成员. 1.接口存 ...

  7. CryptoJS简单使用(request.js) 拦截器的使用

    首先准备一份明文和秘钥: var plaintText = 'aaaaaaaaaaaaaaaa'; // 明文var keyStr = 'bbbbbbbbbbbbbbbb'; // 一般key为一个字 ...

  8. 【剑指Offer】36、两个链表的第一个公共结点

      题目描述:   输入两个链表,找出它们的第一个公共结点.   解题思路:   本题首先可以很直观的想到蛮力法,即对链表1(假设长度为m)的每一个结点,遍历链表2(假设长度为n),找有没有与其相同的 ...

  9. HTTP 下载文件中文文件名在 Firefox 下乱码问题

    转自:http://www.imhdr.com/991/ HTTP 下载文件,中文文件名在 Firefox 下乱码问题 最近帮助一同事解决 HTTP 下载文件时,中文文件名在 Firefox 下乱码的 ...

  10. [luogu2602 ZJOI2010] 数字计数 (数位dp)

    传送门 Description 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. Input 输入文件中仅包含一行两个整数a.b,含义如上所述. Output ...