2008-06-19

分析测试hadoop中的 WordCount示例程序

关键字: hadoop

在 Eclipse 环境下可以方便地进行 Hadoop 并行程序的开发和调试。推荐使用 IBM MapReduce Tools for Eclipse, 使用这个 Eclipse plugin 可以简化开发和部署 Hadoop 并行程序的过程。
具体说明这里有篇文章:
http://www.ibm.com/developerworks/cn/opensource/os-cn-hadoop2/index.html
关于hadoop自带的WordCount示例程序的分析,上面这个篇文章有很详细的说明,
这里以我们的实际需求:分析日志来简单测试一下,网站apache产生的日志文件经过解析,每条记录会生成以‘|’符号分割的21个字段,如:|1|2|3|4|5|6|......21|这个形式的日志文件,而WordCount是以空格来区隔每个单词来计算的,所以我们要修改map方法中的StringTokenizer,让其以‘|’分割计算:

public static class StringTokenizers extends StringTokenizer{
	public StringTokenizers(String str) {
		super(str, "[|]\n\r\f", false);
	}
}

这样就ok了

但这个例子会把这21个字段都进行统计,实际工作只需要统计某些列就行了,假如第13列表示唯一cookie数字值,只要用户访问了网站哪个页面,都会记录下来,这里要求计算这个用户每小时/每天/每月访问网站的url次数,我们进一步修改,首先建立一个logbean,这个bean有21个属性,分别代表日志文件中的21个字段,构造函数分别给这些属性赋值:

public class logbean {
	private String ip;
	private String time;
	private String type;
	private String cookie;
	//...
	public logbean(String line) throws Exception{
		Hashtable ret = null;
		if(line != null){
			ret = Split.split(line, "|");
			this.ip = ret.get(1).toString();
			this.time = ret.get(2).toString();
			this.type = ret.get(3).toString();
			this.cookie = ret.get(13).toString();
			//...
		}
	}
	//other get set
}
/**
 *按照‘|’分割字符串
 */
public static Hashtable split(String fieldsru, String tag){  
	Hashtable returnarray = new Hashtable();  
	char dot = tag.charAt(0);  
	String field;  
	field = fieldsru + dot;  
	int num = 0;  
	int field_len = field.length();  
	for (int i = 0; i < field_len; i++)  
	{  
		if (field.charAt(i) == dot)  
		{  
			num++;  
		}  
	} 
	int begin = 0;  
	int end;  
	for (int j = 0; j < num; j++)  
	{  	
		end = field.indexOf(dot, begin);  
		returnarray.put(new Integer(j), field.substring(begin, end));  
		begin = end + 1;  
	}  
	return returnarray;  
}	
/**我们再修改WordCount中的map方法
   * value 是文本文件中的一行,利用 StringTokenizer 将这个字符串拆成单词,
   * 然后将输出结果 <单词,1> 写入到 org.apache.hadoop.mapred.OutputCollector 中
   */
public void map(LongWritable key, Text value,
		OutputCollector<Text, IntWritable> output, Reporter reporter)
		throws IOException {
	String line = value.toString();
	String l = "";
	String regEx = "\\d+";
	if (line != null) {
		try{					
			LogAccess log = new LogAccess(line);
			if(!log.getCookie().equals("") && log.getCookie() != null 
					&& Pattern.matches(regEx,log.getCookie()))
				l = log.getCookie().toString();
			
		}catch(Exception e){
			//e.printStackTrace();
		}
		StringTokenizer itr = new StringTokenizer(l);
		while (itr.hasMoreTokens()) {
			word.set(itr.nextToken());
			output.collect(word, one);
		}
	}

}

 好了,在运行WordCount时,别忘了添加2个参数:/temp/in(要统计的文件存放目录)   /temp/out(输出结果目录)

 

评论
发表评论

您还没有登录,请登录后发表评论

blank
搜索本博客
我的相册
5c2c51d9-1a15-3713-8084-e1742c808801-thumb
P1080256
共 30 张
存档
最新评论