hadoop入门——wordcount

这篇博客介绍了如何使用Hadoop进行WordCount操作。首先,作者分享了经过修改的源码,该源码能从指定文件读取数据并写入系统文件。接着,详细阐述了将代码打包为jar文件的过程。然后,通过WinSCP将jar包上传到Hadoop集群,并在/home/tseg/zq目录下创建输入和输出文件。最后,在PuTTY中运行命令执行WordCount任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

源码

根据网上的实例,自己稍作修改,把文件读入输出地址,写在系统文件中,通过读文件控制。

import java.io.*;
import java.io.IOException;
import java.util.StringTokenizer;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
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.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;

public class WordCount {

	/**
	 * 
	 * @param args
	 * @throws IOException
	 * @throws ClassNotFoundException
	 * @throws InterruptedException
	 */
	public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
		// TODO Auto-generated method stub
		Configuration conf = new Configuration();// 取得系统的参数
		// if (args.length != 2) { // 判断一下命令行输入路径/输出路径是否齐全,即是否为两个参数
		// System.err.println("Usage: wordcount <in> <out>");
		// System.exit(2); // 若非两个参数,即退出
		// }
		Job job = new Job(conf, "My Word Count"); // 此程序的执行,在hadoop看来是一个Job,故进行初始化job操作
		/* 读取文件,文件中写了本次要处理的.txt地址和输出地址,用分好隔开 */
		FileSystem fs = FileSystem.get(conf);
		FSDataInputStream fin = fs.open(new Path("/user/zq/text.txt"));
		BufferedReader in = null;
		String line, inpath, outpath;
		inpath = outpath = null;
		try {
			in = new BufferedReader(new InputStreamReader(fin, "UTF-8"));
			if ((line = in.readLine()) != null) {
				String[] str = line.split(";");
				inpath = str[0];
				outpath = str[1];
			}
		} finally {
			if (in != null)
				in.close();
		}
		if (fs.exists(new Path(outpath))) {
			fs.delete(new Path(outpath), true);
		}
		job.setJarByClass(WordCount.class); // 可以认为成,此程序要执行MyWordCount.class这个字节码文件
		job.setMapperClass(TokenizerMapper.class); // 在这个job中,我用TokenizerMapper这个类的map函数
		job.setReducerClass(IntSumReducer.class); // 在这个job中,我用IntSumReducer这个类的reduce函数
		job.setOutputKeyClass(Text.class); // 在reduce的输出时,key的输出类型为Text
		job.setOutputValueClass(IntWritable.class);// 在reduce的输出时,value的输出类型为IntWritable
		FileInputFormat.addInputPath(job, new Path(inpath)); // 初始化要计算word的文件的路径
		FileOutputFormat.setOutputPath(job, new Path(outpath)); // 初始化要计算word的文件的之后的结果的输出路径
		System.exit(job.waitForCompletion(true) ? 0 : 1);
		// 这里就是真正的去提交job到hadoop上去执行了,意思是指如果这个job真正的执行完了则主函数退出了,
		// 若没有真正的执行完就退出了,则为非法退出
	}

	// Mapper<input_Key_Type,input_Value_Type,output_key_type,output_value_type>
	// 这里的Text相当于jdk中的String,IntWritable相当于jdk的int类型
	public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> {

                // 声明一个IntWritable变量,作计数用,每出现一个key,给其一个value=1的值		
                private final static IntWritable one = new IntWritable(1);
		private Text word = new Text();// 用来暂存map输出中的key值,Text类型的,故有此声明

		/*
		 * 这里就是map函数,也用到了范型,它是和Mapper抽象类中的相对应的,此处的Object key, Text
		 * value的类型和上边的Object,Text是相对应的,而且最好一样,不然的话,多数情况运行时会报错。
		 */
		public void map(Object key, Text value, Context context) {
			String[] str = value.toString().split(" ");
			for (String s : str) {
				word.set(s);// 出现一个单词就给它设成一个key并将其值设为1
				try {
					context.write(word, one);// 输出设成的key/value值
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	public static class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
		private IntWritable result = new IntWritable();

		public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException,
				InterruptedException {
			int sum = 0;
			/*
			 * 由于map的打散,这里会得到如,{key,values}={"hello",{1,1,1,1,1,1,....}},这样的集合
			 * 这里需要逐一将它们的value取出来予以相加,取得总的出现次数,即为汇和
			 */
			for (IntWritable val : values) {
				sum += val.get();
			}
			result.set(sum);// 将values的和取得,并设成result对应的值
			context.write(key, result);
		}
	}
}


确认没错后,打成jar包

运行:

启动WinSCP,连上集群。把jar包放在自己的文件夹内,如 /home/tseg/zq。

创建文件 /user/zq/text.txt,里面写明输入输出地址,如/user/zq/t.txt;/user/zq/out。 然后根据输入地址(/user/zq/t.txt),创建相应的准备处理的文件(就是wordcount要处理的)。

在PuTTY中打开会话窗口。执行wordcount

tseg@dell1:~$ cd /home/tseg/zq
tseg@dell1:~/zq$ hadoop jar wordcount.jar

运行完毕后,列出输出目录表

tseg@dell1:~$ cd zq
tseg@dell1:~/zq$ hadoop fs -ls /user/zq/out
Found 2 items
drwxr-xr-x   - tseg supergroup          0 2014-03-19 15:38 /user/zq/out/_logs
-rw-r--r--   2 tseg supergroup         65 2014-03-19 15:39 /user/zq/out/part-r-00000

显示输出结果:

tseg@dell1:~/zq$ hadoop fs -cat /user/zq/out/part-r-00000
        1
a       1
b       1
c       2
d       4
e       5
f       3
g       2
h       1
r       4
s       3
sd      1
t       2
w       1
y       2
yu      1



 
 

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值