您的位置:首页 > 编程语言 > PHP开发

mapreduce程序编写注意事项

2012-07-12 17:15 281 查看
任何一个解决方案都不可能做到天衣无缝,在不断出现的应用面前,一定会不断暴露出问题,暴露出问题就要解决。

问题1.与同一个KEY相关联的数据不能太多。

需求如下:

 

 假如有如下的数据(我尽量简化字段):

 域名              QQ号码         性别。

 www.qq.com   21201421      男

 ....

 我需要做类似如下功能的统计 select count(distinct QQ号码) from 数据源 group by 性别。

 

 根据上次的文章,我们可能的做法如下:

 map(K1 key, Text value, OutputCollector<K2, V2> output, Reporter reporter)

 {

    //如何抽取字段我就不多说了,大家应该都清楚了。

    //关键就是这个KEY的取值。

  

    key = 性别+"_UV";

    value = QQ号码

    //将找到的key->value对反馈给框架  

    Output.emit(Key ,value); 

 }

 

 2.Reduce方法需要做什么

 

 void reduce(Text key, Iterator<Text> values,

 

               OutputCollector<Text, Text> output, Reporter reporter)

 

 {

 

  if( postFix( key ) == "_UV" ) //判断是否是用户数这个指标相关的数据

  

  {

  

    //values中的数据就是从各台机器上归总过来的QQ号码

  

    String uv = distinctCount( values );

  

    //push出最终结果

  

    Output.emit(key,uv );

  

  }

 

 }

 

      这样的方式乍看上去没什么问题,但是如果真正提交任务,很有可能将多个机器磁盘撑爆都无法完成任务的执行,问题在哪里呢?

     关键就是KEY值的生成,因为这个需求是按照性别进行统计分析,很显然最终会有两个KEY:"男性_UV","女性_UV",也就是说这个job只有两个reduce任务,所有男性的QQ号码会集中到一台机器,所有女性的QQ号码也会集中到一台机器,这就导致承担reduce任务的机器负载过大,如果涉及的数据量过大,很可能任务就会执行失败。


  

  问题就在这里,想必大家都已经清楚了,那么如何解决这个问题呢?

  解决办法:将KEY打散。
 

  还是这个需求。

  map(K1 key, Text value, OutputCollector<K2, V2> output, Reporter reporter)

 {

  //关键就是这个KEY的取值,我们按照QQ号码后5五位进行数据打散。

  key = 性别+"_UV_"+$func_取QQ号码后五位(QQ号码);

  value = QQ号码

  //将找到的key->value对反馈给框架  

  Output.emit(Key ,value); 

 }

 

 2.Reduce方法需要做什么(reduce代码不做任何变化

 

 void reduce(Text key, Iterator<Text> values,

 

               OutputCollector<Text, Text> output, Reporter reporter)

 

 {

 

  if( postFix( key ) == "_UV" ) //判断是否是用户数这个指标相关的数据

  

  {

  

    //values中的数据就是从各台机器上归总过来的QQ号码

  

    String uv = distinctCount( values );

  

    //push出最终结果

  

    Output.emit(key,uv );

  

  } 

 }

 
 这样就会有很多个类似于如下格式的KEY "男性_UV_00000" "男性_UV_00001" "男性_UV_00002" ..... "男性_UV_99999" (女性时一样)

 也就是说

 原来的统计结果为:

 男性_UV: XXXXXX

 女性_UV:XXXXXX

 

 而现在的统计结果为:

 以00000结尾的男性的QQ号码_UV: XXXXX

 以00001结尾的男性的QQ号码_UV: XXXXX

 以00002结尾的男性的QQ号码_UV: XXXXX

 .....

 以99999结尾的男性的QQ号码_UV: XXXXX

 

 以00000结尾的女性的QQ号码_UV: XXXXX

 以00001结尾的女性的QQ号码_UV: XXXXX

 以00002结尾的女性的QQ号码_UV: XXXXX

 .....

 以99999结尾的女性的QQ号码_UV: XXXXX

 

 拿到结果再做一次统计操作就可以得到整体指标数据了。

转自:
http://blog.csdn.net/sxf_824/article/details/4842126
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息