分享

hadoop(大数据)统计相同手机号的总数(优化)

fish_tx 2015-10-22 17:24:11 发表于 介绍解说 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 0 13830
本帖最后由 fish_tx 于 2015-10-22 18:00 编辑

hadoop(大数据)统计相同手机号的总数
http://www.aboutyun.com/thread-15605-1-1.html

参考:
[大牛翻译系列]Hadoop15MapReduce 性能调优:优化MapReduce的用户JAVA代码

Mapper
package com.fish.had.cellphonenumbercount;

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;

public class CellPhoneNumberMapper extends Mapper<LongWritable, Text, Text, LongWritable>{

        final LongWritable ONE = new LongWritable(1L);
        Text v2 = new Text();

        @Override
        protected void map(LongWritable k1, Text v1,
                        Mapper<LongWritable, Text, Text, LongWritable>.Context context)
                        throws IOException, InterruptedException {
                String v = v1.toString();
                /*
                if(null != v && !"".equals(v)){
                        String[] ss = v.split("\t");//2
                        if(ss.length > 2){
                                if(ss[2].length() == 11 && ss[2].indexOf(".") < 0){
                                        context.write(new Text(ss[2]), ONE);
                                }
                        }
                }
                */
                //--优化-----------------------------------------------------------------
                if(null != v && !"".equals(v)){
                        String[] ss = StringUtils.split(v, "\t");
                        if(ss.length > 2){
                                if(ss[2].length() == 11 && ss[2].indexOf(".") < 0){
                                        v2.set(ss[2]);
                                        context.write(v2, ONE);
                                }
                        }
                }
        }
}


正则表达式
正则表达式有非常丰富灵活的特性。然而灵活性意味着性能下降。有的时候,性能会降低到不可接受的地步。那么,作为一般准则,就应该在MapReduce中避免使用正则表达式。如果非用不可,也应该尽量寻找替代方法。

字符串令牌化(TOKENIZATION)
JAVA的文档推荐使用String.split和Scanner类来实现字符串令牌化。实际上,它们都是基于正则表达式,在MapReduce中 会很慢。然后,就要考虑用JAVA文档不推荐的StringTokenizer。但是,StringTokenizer的算法性能也不是最优。 Apache commons中的StringUtils类效率要更好。
String[] ss = StringUtils.split(v, "\t");

对象重用
第二个消耗CPU时间的是类似如下的代码:
context.write(new Text(ss[2]), ONE);
由于这段代码在每个键值对都要执行一次,就要执行成千上万次。代码就会在对象分配上浪费大量的时间。对象分配在JAVA中是非常昂贵的,包含创建时调用CPU,销毁时调用垃圾收集器。如果能够重用,将节约大量的时间。以下代码介绍如何达到最大重用率:
Text v2 = new Text();

.....

if(ss[2].length() == 11 && ss[2].indexOf(".") < 0){
           v2.set(ss[2]);
           context.write(v2, ONE);
}

本帖被以下淘专辑推荐:

没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条