Spark平台(精简版四)Hadoop之HDFS和WordCount

完整目录、平台简介、安装环境及版本:参考《Spark平台(精简版)概览》

四、操作HDFS目录

4.1 创建与查看mkdir/ls

hduser@master:~$ hadoop fs -mkdir /usr
hduser@master:~$ hadoop fs -mkdir /usr/hduser
hduser@master:~$ hadoop fs -mkdir /usr/hduser/test
hduser@master:~$ hadoop fs -ls /
hduser@master:~$ hadoop fs -ls /usr
hduser@master:~$ hadoop fs -ls /usr/hduser

4.1.1 递归显示

hduser@master:~$ hadoop fs -ls -R /

4.1.1 多级目录

hduser@master:~$ hadoop fs -mkdir -p /dir1/dir2/dir3
hduser@master:~$ hadoop fs -ls -R /

4.2 本地复制到HDFS copyFromLocal/put

4.2.1 拷贝

hduser@master:~$ hadoop fs -copyFromLocal /usr/local/hadoop/README.txt /usr/hduser/test
hduser@master:~$ hadoop fs -copyFromLocal /usr/local/hadoop/README.txt /usr/hduser/test/test1.txt
hduser@master:~$ hadoop fs -ls /usr/hduser/test

查看拷贝结果:

查看:hduser@master:~$ hadoop fs -cat /usr/hduser/test/test1.txt

4.2.2 强制覆盖

hduser@master:~$ hadoop fs -copyFromLocal /usr/local/hadoop/README.txt /usr/hduser/test
hduser@master:~$ hadoop fs -copyFromLocal -f /usr/local/hadoop/README.txt /usr/hduser/test

4.2.3 复制多个文件

hduser@master:~$ hadoop fs -copyFromLocal /usr/local/hadoop/NOTICE.txt /usr/local/hadoop/LICENSE.txt  /usr/hduser/test
hduser@data3:~$ hadoop fs -ls /usr/hduser/test

4.2.4 复制目录

hduser@master:~$ hadoop fs -copyFromLocal /usr/local/hadoop/etc  /usr/hduser/test
hduser@master:~$ hadoop fs -ls /usr/hduser/test

三个节点查看拷贝结果:

4.3 HDFS复制到本地 copyToLocal/get

4.3.1 文件复制

hduser@master:~$ mkdir test
hduser@master:~$ cd test
hduser@master:~/test$ ll
hduser@master:~/test$ hadoop fs -copyToLocal /usr/hduser/test/test1.txt
hduser@master:~/test$ ll

4.3.2 目录复制

hduser@master:~/test$ hadoop fs -copyToLocal /usr/hduser/test/etc
hduser@master:~/test$ ll

4.4 HDFS目录间复制

hduser@master:~/test$ hadoop fs -mkdir /usr/hduser/test/temp
hduser@master:~/test$ hadoop fs -cp /usr/hduser/test/README.txt /usr/hduser/test/temp
hduser@master:~/test$ hadoop fs -ls /usr/hduser/test/temp

4.5 删除HDFS文件及目录

Hadoop fs –rm /usr/hduser/test/test1.txt
hduser@master:~/test$ hadoop fs -rm -R /usr/hduser/test/etc

4.6 通过页面管理

浏览器输入:http://192.168.0.50:50070

点击文件,而非目录

4.6.1 下载故障

五、MapReduce 之 WordCount

5.1 前期准备

创建wordcount目录:mkdir -p ~/wordcount/input
环境变量:sudo gedit ~/.bashrc
export PATH=${JAVA_HOME}/bin:${PATH}
export HADOOP_CLASSPATH=${JAVA_HOME}/lib/tools.jar
启动环境变量:source ~/.bashrc

5.2 创建并编译

sudo gedit WordCount.java
import java.io.IOException;
import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;
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;

public class WordCount {
    //1、Object:输入< key, value >对的 key 值,此处为文本数据的起始位置的偏移量。在大部分程序下这个参数可以直接使用 Long 类型,源码此处使用Object做了泛化。 
    //2、Text:输入< key, value >对的 value 值,此处为一段具体的文本数据。 
    //3、Text:输出< key, value >对的 key 值,此处为一个单词。 
    //4、IntWritable:输出< key, value >对的 value 值,此处固定为 1 。IntWritable 是 Hadoop 对 Integer 的进一步封装,使其可以进行序列化。
    public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable>{//(keyIn、valueIn、keyOut、valueOut),即Map()任务的输入和输出都是< key,value >对的形式。
		//one:类型为Hadoop定义的 IntWritable 类型,其本质就是序列化的 Integer ,one 变量的值恒为 1 。       
		private final static IntWritable one = new IntWritable(1);
		//word:因为在WordCount程序中,Map 端的任务是对输入数据按照单词进行切分,每个单词为 Text 类型。  
		private Text word = new Text();


		//key: 输入数据在原数据中的偏移量。 
		//value:具体的数据数据,此处为一段字符串。 
		//context:用于暂时存储 map() 处理后的结果。
		public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
			//方法内部首先把输入值转化为字符串类型,并且对Hadoop自带的分词器 StringTokenizer 进行实例化用于存储输入数据。之后对输入数据从头开始进行切分,把字符串中的每个单词切分成< key, value >对的形式,如:< hello , 1>、< world, 1> …
			StringTokenizer itr = new StringTokenizer(value.toString());//以空白字符(“ ”,“\t”,“\n”)为分隔符分割字符串。 
			//hasMoreTokens():执行每个标记的语言符号,nextToken():返回下一个语言符号。
			while (itr.hasMoreTokens()) {
				word.set(itr.nextToken());
				context.write(word, one);
			}
		}
    }

    //1、Text:输入< key, value >对的key值,此处为一个单词 
    //2、IntWritable:输入< key, value >对的value值。 
    //3、Text:输出< key, value >对的key值,此处为一个单词 
    //4、IntWritable:输出< key, value >对,此处为相同单词词频累加之后的值。实际上就是一个数字。
    public static class IntSumReducer extends Reducer<Text,IntWritable,Text,IntWritable> {//(keyIn、valueIn、keyOut、valueOut),即Reduce()任务的输入和输出都是< key,value >对的形式。

        private IntWritable result = new IntWritable();
		//1、Text:输入< key, value >对的key值,也就是一个单词 
		//2、value:这个地方值得注意,在前面说到了,在MapReduce任务中,除了我们自定义的map()和reduce()之外,在从map 刀reduce 的过程中,系统会自动进行combine、shuffle、sort等过程对map task的输出进行处理,因此reduce端的输入数据已经不仅仅是简单的< key, value >对的形式,而是一个一系列key值相同的序列化结构,如:< hello,1,1,2,2,3…>。因此,此处value的值就是单词后面出现的序列化的结构:(1,1,1,2,2,3…….) 
		//3、context:临时存储reduce端产生的结果
        public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
            int sum = 0;
            for (IntWritable val : values) {
                sum += val.get();
            }
            result.set(sum);
            context.write(key, result);
        }
    }

    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf, "word count");// 实例化job,传入参数,job的名字叫 word count
        job.setJarByClass(WordCount.class);//使用反射机制,加载程序
        job.setMapperClass(TokenizerMapper.class);//设置job的map阶段的执行类
        job.setCombinerClass(IntSumReducer.class);//设置job的combine阶段的执行类
        job.setReducerClass(IntSumReducer.class); //设置job的reduce阶段的执行类
        job.setOutputKeyClass(Text.class); //设置程序的输出的key值的类型
        job.setOutputValueClass(IntWritable.class);//设置程序的输出的value值的类型
        FileInputFormat.addInputPath(job, new Path(args[0]));//获取我们给定的参数中,输入文件所在路径
        FileOutputFormat.setOutputPath(job, new Path(args[1]));//获取我们给定的参数中,输出文件所在路径
        System.exit(job.waitForCompletion(true) ? 0 : 1); //等待任务完成,任务完成之后退出程序
    }
}
编译:hduser@master:~/wordcount$ hadoop com.sun.tools.javac.Main WordCount.java
打包:hduser@master:~/wordcount$ jar cf wc.jar WordCount*.class

5.3 准备测试数据

hduser@master:~/wordcount$ cp /usr/local/hadoop/LICENSE.txt ~/wordcount/input

5.3.1 故障:安全模式

hduser@master:~$ hadoop fs -mkdir -p /usr/hduser/wordcount/input
hduser@master:~$ hadoop dfsadmin -safemode leave

5.3.2 上传数据

目录:hadoop fs -mkdir -p /user/wordcount/input
上传:hduser@master:~$ hadoop fs -copyFromLocal ~/wordcount/input/LICENSE.txt /usr/hduser/wordcount/input
查看:hduser@master:~$ hadoop fs -ls -R /usr/hduser/wordcount

5.4 运行

hduser@master:~$ cd wordcount/
运行:hduser@master:~/wordcount$ hadoop jar wc.jar WordCount /usr/hduser/wordcount/input/LICENSE.txt /usr/hduser/wordcount/output
结果文件:hduser@master:~/wordcount$ hadoop fs -ls /usr/hduser/wordcount/output

5.5 查看运行结果

查看:hduser@master:~/wordcount$ hadoop fs -cat /usr/hduser/wordcount/output/part-r-00000

发表回复