版权声明:本文为博主原创文章,未经博主同意不得转载。

https://blog.csdn.net/jdh99/article/details/37565825

hadoop编程:分析CSDN注冊邮箱分布情况

本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.

环境:

主机:Ubuntu10.04

hadoop版本号:1.2.1

开发工具:eclipse4.4.0

说明:

要求:原始数据共6428632条。分析不同邮箱的注冊情况,并按使用人数从大到小排序。

分析:hadoop自带一个排序,是按key值来进行排序的。要按值(value)进行排序,须要二次排序。

步骤:

1.job1:统计不同注冊邮箱的使用人数,用默认的key值排序,保存在HDFS系统中

2.job2:对job1的输出进行二次排序,按值从大到小排序

结果输出:

使用人数在1W以上的邮箱共同拥有24个:

qq.com    1976196
163.com    1766927
126.com    807895
sina.com    351596
yahoo.com.cn    205491
hotmail.com    202948
gmail.com    186843
sohu.com    104736
yahoo.cn    87048
tom.com    72365
yeah.net    53295
21cn.com    50710
vip.qq.com    35119
139.com    29207
263.net    24779
sina.com.cn    19156
live.cn    18920
sina.cn    18601
yahoo.com    18454
foxmail.com    16432
163.net    15176
msn.com    14211
eyou.com    13372
yahoo.com.tw    10810


源码:

JOB1:统计不同注冊邮箱的人数

CsdnData.java

package com.bazhangkeji.hadoop;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser; public class CsdnData
{
public static void main(String[] args) throws Exception
{
Configuration conf = new Configuration();
String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
if (otherArgs.length != 2)
{
System.err.println("Usage: csdndata <in> <out>");
System.exit(2);
}
Job job = new Job(conf, "csdndata"); job.setJarByClass(CsdnData.class);
job.setMapperClass(MapData.class); job.setReducerClass(ReducerData.class);
job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}

MapData.java

package com.bazhangkeji.hadoop;
import java.io.IOException; import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Mapper.Context; public class MapData extends Mapper<Object, Text, Text, IntWritable>
{
IntWritable one = new IntWritable(1);
Text word = new Text(); public void map(Object key, Text value, Context context) throws IOException, InterruptedException
{
StringBuffer str_in = new StringBuffer();
StringBuffer str_out = new StringBuffer();
int index = 0; //初始化字符串
str_in.setLength(0);
str_out.setLength(0);
str_in.append(value.toString()); //获得邮箱的起始位置
index = str_in.toString().lastIndexOf('@');
if (index != -1)
{
word.set(str_in.toString().substring(index + 1).trim().toLowerCase());
context.write(word, one);
}
}
}

ReducerData.java

package com.bazhangkeji.hadoop;
import java.io.IOException; import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.Reducer.Context; public class ReducerData extends Reducer<Text,IntWritable,Text,IntWritable>
{
IntWritable result = new IntWritable(); public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException
{
int sum = 0;
for (IntWritable val : values)
{
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
}

JOB2:对job1的输出进行二次排序。按值从大到小排序

SortSecond.java

package com.bazhangkeji.hadoop2;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser; public class SortSecond
{
public static void main(String[] args) throws Exception
{
Configuration conf = new Configuration();
String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
if (otherArgs.length != 2)
{
System.err.println("Usage: csdndata <in> <out>");
System.exit(2);
}
Job job = new Job(conf, "sortsecond");
job.setJarByClass(SortSecond.class); job.setMapperClass(MapSecond.class);
job.setReducerClass(ReduceSecond.class); job.setSortComparatorClass(SortMy.class); //设置自己定义二次排序策略 job.setOutputKeyClass(KeyMy.class);
job.setOutputValueClass(IntWritable.class); FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}

MapSecond.java

package com.bazhangkeji.hadoop2;
import java.io.IOException;
import java.util.StringTokenizer; import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Mapper.Context; public class MapSecond extends Mapper<LongWritable, Text, KeyMy, IntWritable>
{
IntWritable one = new IntWritable(1);
Text word = new Text();
KeyMy keymy = new KeyMy(); public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException
{
String str_in = value.toString();
int index = 0; index = str_in.indexOf('\t');
if (value.toString().length() > 3 && index != -1)
{
String str1 = str_in.substring(0, index);
String str2 = str_in.substring(index + 1); if (str1.length() != 0 && str2.length() != 0)
{
one.set(Integer.parseInt(str2));
word.set(str1);
keymy.setFirstKey(word);
keymy.setSecondKey(one);
context.write(keymy, one);
}
}
}
}

ReduceSecond.java

package com.bazhangkeji.hadoop2;
import java.io.IOException; import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.Reducer.Context; public class ReduceSecond extends Reducer<KeyMy,IntWritable,Text,IntWritable>
{
IntWritable result = new IntWritable(); public void reduce(KeyMy key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException
{
context.write(key.getFirstKey(), key.getSecondKey());
}
}

KeyMy.java

package com.bazhangkeji.hadoop2;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableComparable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 自己定义组合键
*/
public class KeyMy implements WritableComparable<KeyMy>{
private static final Logger logger = LoggerFactory.getLogger(KeyMy.class);
private Text firstKey;
private IntWritable secondKey;
public KeyMy() {
this.firstKey = new Text();
this.secondKey = new IntWritable();
}
public Text getFirstKey() {
return this.firstKey;
}
public void setFirstKey(Text firstKey) {
this.firstKey = firstKey;
}
public IntWritable getSecondKey() {
return this.secondKey;
}
public void setSecondKey(IntWritable secondKey) {
this.secondKey = secondKey;
}
@Override
public void readFields(DataInput dateInput) throws IOException {
// TODO Auto-generated method stub
this.firstKey.readFields(dateInput);
this.secondKey.readFields(dateInput);
}
@Override
public void write(DataOutput outPut) throws IOException {
this.firstKey.write(outPut);
this.secondKey.write(outPut);
}
/**
* 自己定义比較策略
* 注意:该比較策略用于 mapreduce的第一次默认排序,也就是发生在map阶段的sort小阶段,
* 发生地点为环形缓冲区(能够通过io.sort.mb进行大小调整)
*/
@Override
public int compareTo(KeyMy KeyMy) {
logger.info("-------KeyMy flag-------");
return this.firstKey.compareTo(KeyMy.getFirstKey());
}
}

SortMy.java

package com.bazhangkeji.hadoop2;

import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 自己定义二次排序策略
*/
public class SortMy extends WritableComparator {
private static final Logger logger = LoggerFactory.getLogger(SortMy.class);
public SortMy() {
super(KeyMy.class,true);
}
@Override
public int compare(WritableComparable KeyMyOne,
WritableComparable KeyMyOther)
{
logger.info("---------enter SortMy flag---------"); KeyMy c1 = (KeyMy) KeyMyOne;
KeyMy c2 = (KeyMy) KeyMyOther; return c2.getSecondKey().get()-c1.getSecondKey().get();//0,负数,正数
}
}


參考资料:

1.《hadoop权威指南》

2.  http://zengzhaozheng.blog.51cto.com/8219051/1379271

hadoop编程:分析CSDN注冊邮箱分布情况的更多相关文章

  1. 《解读window核心编程》 之 注冊表

    1 注冊表的作用及组织形式 Windows系统使用注冊表来存储系统和应用程序配置数据.非常多系统和应用程序重要的配置的信息都存储在注冊表中. 注冊表是一种以树型结构组织的数据库.树的每个节点称 作键( ...

  2. 协议的注冊与维护——ndpi源代码分析

    在前面的文章中,我们对ndpi中的example做了源代码分析.这一次我们将尽可能深入的了解ndpi内部的结构和运作.我们将带着以下三个目的(问题)去阅读ndpi的源代码. 1.ndpi内部是怎么样注 ...

  3. YII用户注冊和用户登录(三)之模型中规则制定和分析

    3 模型中规则制定和分析 YII模型主要分为两类,一个数据模型,处理和数据库相关的增删改查.继承CActiveRecord.还有一个是表单模型,继承CFormModel.不与数据库进行交互.操作与数据 ...

  4. CLion注冊码算法逆向分析实录(纯研究)

    声明 CLion程序版权为jetBrains全部.注冊码授权为jetBrains及其付费用户全部,本篇仅仅从兴趣出发,研究其注冊码生成算法. 不会释出不论什么完整的源码. 网上查了下.已有注冊机,所以 ...

  5. 从注冊流程 分析怎样安全退出多个Activity 多种方式(附DEMO)

    前言 因为一个同学问到我怎样依照一个流程走好之后回到首页.我曾经看到过4个解决方式,后来发现有做个记录和总结的必要,就写了这篇博文. (之前看小强也写过一篇,这里通过自身的分析完整的总结一下下面6种方 ...

  6. 免费edu邮箱申请注冊地址

    几个国外.edu邮箱注冊地址: 注冊地址:http://mail.alumni.fandm.edu/reg/reg_pangia.asp   @alumni.fandm.edu 注冊地址: http: ...

  7. 【spring源代码分析】--Bean的解析与注冊

    接着上一节继续分析,DefaultBeanDefinitionDocumentReader的parseBeanDefinitions方法: protected void parseBeanDefini ...

  8. Android Binder分析二:Natvie Service的注冊

    这一章我们通过MediaPlayerService的注冊来说明怎样在Native层通过binder向ServiceManager注冊一个service,以及client怎样通过binder向Servi ...

  9. YII用户注冊和用户登录(二)之登录和注冊在视图通过表单使用YII小物件并分析

    2 登录和注冊在视图通过表单使用YII小物件并分析 <?php $form = $this -> beginWidget('CActiveForm', array( 'enableClie ...

随机推荐

  1. Redis-ha(sentinel)

    redis的sendtinel 是用来管理多个redis服务器的 作用 • 监控:监控主从服务器是否运作正常(通过给服务器发送心跳包的方式)    • 提醒:当某个Redis服务器出现异常时,可以通过 ...

  2. 基于Java Mina 和Netty 通信框架的JT/T809转发服务器设计

    Apache MINA 是 Apache 组织的一个开源项目,为开发高性能和高可用性的网络应用程序提供了非常便利的框架. 也是Java开发者的一个福利(.NET目前还没有类似封装的这么好的基础sock ...

  3. PHP学习笔记(3)GD库画图

    <?php //加header头,不然浏览器乱码 header("content-type: image/png"); //创建画布资源 $img = imagecreate ...

  4. gm: error while loading shared libraries: libpng15.so.15: cannot open shared object file: No such file or directory

    安装gm库产生问题 解决方案: # cat /etc/ld.so.confinclude ld.so.conf.d/*.conf# echo "/usr/local/lib" &g ...

  5. TCP编程,Socket通讯

    网络编程分两种,一种是TCP编程,还有一种是UDP编程(点击打开链接).而本文先讲述简单的TCP编程,Socket套接字连接通讯,实现简单的client与server之间的信息传输. 以下是clien ...

  6. 用阿里云搭建Http代理服务器

    先说下我的运行环境: Ubuntu16.04+python3.5,用的是阿里云ECS乞丐版. 搭建步骤: [python] view plain copy 0. 直接用xshell或putty远程到云 ...

  7. 微信小程序3 - 对象的合并

    ES6中 Object.assign方法用于对象的合并,将源对象( source )的所有可枚举属性,复制到目标对象( target ). 限制:   只是浅拷贝, 即 内部对象 不会拷贝,只是 引用 ...

  8. 第一百五十六节,封装库--JavaScript,延迟加载

    封装库--JavaScript,延迟加载 延迟加载的好处,就是在浏览器视窗外的图片,不加载,拖动鼠标到浏览器视窗内后加载,用户不看的图片就不用加载,可以减少服务器大量流量 将图片的src地址用一张统一 ...

  9. 【BZOJ】3314: [Usaco2013 Nov]Crowded Cows(单调队列)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3314 一眼就是维护一个距离为d的单调递减队列... 第一次写.....看了下别人的代码... 这一题 ...

  10. 我的第一个reactnative

    由于在做极光推送,前端使用的框架是reactnative,后台写好后为了测试一下,所以按照react官方的教程搭了遍react. 开发环境: 1.windows 7(建议各位如果开发react的最好还 ...