hadoop 中reducer非常慢 算法很简单

zjh9058 2012-06-17 01:37:53
我的算法非常简单 数据文件24个G 每行都是有两个数字组成例如
12 14
12 15
12 29
13 90
。。。。
算法就是设置第一个数字为key 然后找这个key对应的所有的第二个数字 ,有点像社交网络里找“粉丝”的意思
最后输出为
12 [14,15,29..]
13 [.....]

但是不知道为什么放到hadoop 里面跑 map里面很快 reduce的时候就非常非常慢 reduce 里面67%之前很快 67%之后到67.42%用了尼玛一个多小时
而我跑wordcount(hadoop官网的例子)统计这24个G的数据里面 第一个数字出现的次数 这个却挺快的
是不是算法的问题? 我的code如下: 求各路大神指点

package org.myorg;
import java.io.IOException;
import java.util.*;

import org.apache.hadoop.fs.Path;
import org.apache.hadoop.conf.*;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapred.*;
import org.apache.hadoop.util.*;


public class followerTwitter {

public static class Map extends MapReduceBase implements Mapper<LongWritable, Text, Text, Text> {
//private final static IntWritable one = new IntWritable(1);
private Text twitterID = new Text();
private Text followerID = new Text();

public void map(LongWritable key, Text value, OutputCollector<Text, Text> output, Reporter reporter) throws IOException {
String line = value.toString();
StringTokenizer tokenizer = new StringTokenizer(line);
if (tokenizer.hasMoreTokens()) {

twitterID.set(tokenizer.nextToken());

}

if (tokenizer.hasMoreTokens()) {
followerID.set(tokenizer.nextToken());

}

output.collect(twitterID, followerID);

}
}

public static class Reduce extends MapReduceBase implements Reducer<Text, Text, Text, Text> {
public void reduce(Text key, Iterator<Text> values, OutputCollector<Text, Text> output, Reporter reporter) throws IOException {
Text followers = new Text();
String orginal = "Followers:[";
//Text sum2 = new Text();
while (values.hasNext()) {
Text temp =values.next();
String temps=temp.toString();
orginal = orginal+temps+',';
}

orginal =orginal+']';
Text followerList=new Text(orginal);
output.collect(key, followerList);
}
}


public static void main(String[] args) throws Exception {
JobConf conf = new JobConf(followerTwitter.class);
conf.setJobName("followerTwitter");

conf.setOutputKeyClass(Text.class);
conf.setOutputValueClass(Text.class);

conf.setMapperClass(Map.class);
//conf.setCombinerClass(Reduce.class);
conf.setReducerClass(Reduce.class);

conf.setInputFormat(TextInputFormat.class);
conf.setOutputFormat(TextOutputFormat.class);

FileInputFormat.setInputPaths(conf, new Path(args[0]));
FileOutputFormat.setOutputPath(conf, new Path(args[1]));

JobClient.runJob(conf);
}
}
...全文
412 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
mrsworf 2012-06-19
  • 打赏
  • 举报
回复
reduse用字符串的+操作可能比较慢,改成StringBuilder之类的试试看
另外避免用append 若append多次也会很慢
zjh9058 2012-06-17
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

reduse用字符串的+操作可能比较慢,改成StringBuilder之类的试试看

Java code
//Text followers = new Text();
//String orginal = "Followers:[";
StringBuilder orginal = new StringBuilder("Followers:[");
//Text sum2 ……
[/Quote]
哥!我都要爱上你了!!我之前也用了append 但是是最土的一次一次的append!所以也卡在reducer上了!我用了你的code果断10几分钟reduce完了!现在在merge结果!中国网友太强大了 我爱我的祖国!
brightyq 2012-06-17
  • 打赏
  • 举报
回复
和hadoop没关系,应该是字行串那里:

String temps=temp.toString();
orginal = orginal+temps+',';

字符串拼接时,如果不存在多线程的情况就使用StringBuilder,比StringBuffer要快。
平时用orginal = orginal+temps+',';看不出效率的区别,你这里20G的话,效率就区别很大了。
像1楼那样,用StringBuilder的append方法拼接字符串。
MiceRice 2012-06-17
  • 打赏
  • 举报
回复
另一个可能的原因:数据规模这么大,最后都靠一个地方reduce。

比较怀疑是GC过于频繁导致,请问你内存配置多大?

另外建议你开启GC日志:“-XX:+PrintGCDetails” 然后再跑一次,看最后是不是频繁GC了。
qybao 2012-06-17
  • 打赏
  • 举报
回复
reduse用字符串的+操作可能比较慢,改成StringBuilder之类的试试看

  //Text followers = new Text();
//String orginal = "Followers:[";
StringBuilder orginal = new StringBuilder("Followers:[");
//Text sum2 = new Text();
while (values.hasNext()) {
//Text temp =values.next();
//String temps=temp.toString();
//orginal = orginal+temps+',';
orginal.append(values.next().toString()).append(",");
}

//orginal =orginal+']';
orginal.append("]");
//Text followerList=new Text(orginal);
Text followerList=new Text(orginal.toString());
output.collect(key, followerList);
前言 致谢 关于本书 第1 部分 背景和基本原理 1 跳跃Hadoop 1.1 什么是Hadoop 1.1.1 Hadoop 的核心组件 1.1.2 Hadoop 生态圈 1.1.3 物理架构 1.1.4 谁在使用Hadoop 1.1.5 Hadoop 的局限性 1.2 运行Hadoop 1.2.1 下载并安装Hadoop 1.2.2 Hadoop 的配置 1.2.3 CLI 基本命令 1.2.4 运行MapReduce 作业 1.3 本章小结 第2 部分 数据逻辑. 2 将数据导入导出Hadoop. 2.1 导入导出的关键要素 2.2 将数据导入Hadoop . 2.2.1 将日志文件导入Hadoop 技术点1 使用Flume 将系统日志文件导入HDFS 2.2.2 导入导出半结构化和二进制文件 技术点2 自动复制文件到HDFS 的机制 技术点3 使用Oozie 定期执行数据导入活动 2.2.3 从数据库拉数据 技术点4 使用MapReduce 将数据导入数据库 技术点5 使用Sqoop 从MySQL 导入数据 2.2.4 HBase 技术点6 HBase 导入HDFS 技术点7 将HBase 作为MapReduce 的数据源 2.3 将数据导出Hadoop 2.3.1 将数据导入本地文件系统 技术点8 自动复制HDFS 的文件 2.3.2 数据库 技术点9 使用Sqoop 将数据导入MySQL 2.3.3 Hbase 技术点10 将数据从HDFS 导入HBase 技术点11 使用HBase 作为MapReduce 的数据接收器 2.4 本章小结 3 数据序列化――处理文本文件及其他格式的文件 3.1 了解MapReduce 的输入和输出 3.1.1 数据输入 3.1.2 数据输出 3.2 处理常见的序列化格式 3.2.1 XML . 技术点12 MapReduce 和XML 3.2.2 JSON . 技术点13 MapReduce 和JSON . 3.3 大数据的序列化格式 3.3.1 比较SequenceFiles、Protocol Buffers、Thrift 和 Avro 3.3.2 Sequence File 技术点14 处理SequenceFile 3.3.3 Protocol Buffers 技术点15 整合Protocol Buffers 和MapReduce . 3.3.4 Thrift . 技术点16 使用Thrift 3.3.5 Avro 技术点17 MapReduce 的下一代数据序列化技术 3.4 自定义文件格式 3.4.1 输入输出格式 技术点18 输入和输出格式为CSV 的文件 3.4.2 output committing 的重要性 3.5 本章小结 第3 部分 大数据模式 4 处理大数据的MapReduce 模式 4.1 Join 4.1.1 Repartition Join 技术点19 优化repartition join 4.1.2 Replicated Join 4.1.3 Semi-join 技术点20 实现semi-join 4.1.4 为你的数据挑选最优的合并策略 4.2 排序 4.2.1 二次排序 技术点21 二次排序的实现 4.2.2 整体并行排序 技术点22 通过多个reducer 对key 进行排序 4.3 抽样 技术点23 蓄水池抽样(reservoir 抽样) 4.4 本章小结 5 优化HDFS 处理大数据的技术 5.1 处理小文件 技术点24 使用Avro 存储大量小文件 5.2 通过压缩提高数据存储效率 技术点25 选择合适的压缩解码器 技术点26 在HDFS、MapReduce、Pig 和Hive 使用数据压缩 技术点27 在MapReduce、Hive 和Pig 处理可分割的LZOP 5.3 本章小结 6 诊断和优化性能问题 6.1 衡量MapReduce 和你的环境 6.1.1 提取作业统计信息的工具 6.1.2 监控 6.2 确定性能问题的原因 6.2.1 了解哪些因素会影响MapReduce 作业的性能 6.2.2 map 端异常 技术点28 发现输入数据的坑 技术点29 确定map 端数据倾斜问题 技术点30 判定map 任务吞吐量 技术点31 小文件 技术点32 不可切割的文件 6.2.3 reduce 端问题 技术点33 reducer 任务数过大或过小 . 技术点34 定位reduce 端数据倾斜问题 技术点35 确定reduce 任务是否存在整体吞吐量过低 技术点36 缓的洗牌(shuffle)和排序 . 6.2.4 任务的一般性能问题 技术点37 作业竞争和调度器限制 技术点

50,530

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧