一.HDFS JavaAPI实验
- 查看hdfs文件系统启动状况:在虚拟机输入 jps 回车查看运行进程信息(有无名称结点与数据结点等共6条进程信息,有则已经启动,无则需要启动)。
- 启动hdfs文件系统:在虚拟机输入 start-all.sh 回车等待一段时间直到显示下面6条进程运行的信息。
- 在Linux系统中创建文件hlc.txt :终端根目录创建文件夹:mkdir /hlc ,进入文件夹: cd /hlc , 在该文件夹里创建文件: touch hlc.txt。
- 将该文件上传至hdfs 文件系统:hdfs dfs -put /hlc/hlc.txt。
- 查看上传是否成功:hdfs dfs -ls /hlc。
- 点击运行eclipse软件创建java项目并在src主目录下创建java类文件resetName.java。
- 去往虚拟机桌面,将lib文件夹中拷贝到eclipse 项目src 主目录下。
- 打开拷贝过来的lib文件夹,右键选择build to path 将这些包导入到外部库中。
- 编写resetName.java文件代码(主要利用hdfs的JavaAPI: FileSystem 操作hdfs文件系统中的文件:具体的代码如下)
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.net.URI; public class shiyan1 { private FileSystem fs = null; // 前置注解,在test执行之前运行前置注解标识的方法体代码(当然也有后置代码) @Before public void init() throws Exception { fs = FileSystem.get(new URI("hdfs://192.168.1.2:9000"),new Configuration()); } //测试注解,主要运行测试的线程(可以有多个),模拟main但是用途与限制没有main多且更轻 @Test public void test() throws IOException { boolean rename = fs.rename(new Path("/hlc/hlc.txt"), new Path("/hlc/20hlc.txt")); System.out.println(rename==true?"yes":"no"); } } |
- 点击鼠标右键选择Run As,选择Junit(这个是java开发常用的单元测试框架)运行测试方法:查看控制台输出内容是否为操作成功标识yes。
- 进入Linux终端输入hdfs dfs -ls /hlc 查看文件是否改名为20hlc.txt
二、MapReduce实验
- 查看hdfs文件系统启动状况:在虚拟机输入 jps 回车查看运行进程信息(有无名称结点与数据结点等共6条进程信息,有则已经启动,无则需要启动)。
- 启动hdfs文件系统:在虚拟机输入 start-all.sh 回车等待一段时间直到显示下面6条进程运行的信息。
- 终端输入 hdfs dfs -ls /data 查看是否存在待计算总成绩的源文件
- 点击运行eclipse,创建新的java项目score,点击项目src主目录创建java类文件score.java。
- 去往虚拟机桌面,将lib文件夹中拷贝到eclipse 项目src 主目录下。
- 打开拷贝过来的lib文件夹,右键选择build to path 将这些包导入到外部库中。
- 编写score.java 代码(篇幅较长,代码与注释如下):
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; 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 java.io.IOException; import java.util.Iterator; import java.util.StringTokenizer; /*注意处理的过程是一行数据一行数据的处理之后也是一堆键值一堆键值的处理*/ public class shiyan2 { public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException { /*创建Hdfs作业对象*/ Job job = Job.getInstance(new Configuration()); /*设置主类*/ job.setJarByClass(shiyan2.class); /*设置mapper的主类*/ job.setMapperClass(mapper.class); /*设置reducer的主类*/ job.setReducerClass(reducer.class); /*设置map数据处理之后的键类型所属类*/ job.setMapOutputKeyClass(Text.class); /*设置map数据处理之后的键值类型所属类*/ job.setMapOutputValueClass(IntWritable.class); /*设置输出键类型所属类*/ job.setOutputKeyClass(Text.class); /*设置输出键值类型所属类*/ job.setMapOutputValueClass(IntWritable.class); /*设置作业操控的文件输入的路径*/ FileInputFormat.setInputPaths(job, new Path("hdfs://192.168.1.2:9000/data/resource.txt")); /*设置本次作业处理文件结果的输出路径*/ FileOutputFormat.setOutputPath(job,new Path("hdfs://192.168.1.2:9000/data/out")); /*等待作业完成*/ job.waitForCompletion(true); } static class mapper extends Mapper<LongWritable,Text,Text, IntWritable> { @Override protected void map(LongWritable key, Text value,Context context) throws IOException, InterruptedException { /*将vlaue文本的字符信息变成序列存储在字符串变量里*/ String val = value.toString(); /*按照字符串分词器以换行符号来将我们的字符串变量val分词*/ StringTokenizer stringTokenizer = new StringTokenizer(val,"\n"); while (stringTokenizer.hasMoreElements()){ StringTokenizer tmp = new StringTokenizer(stringTokenizer.nextToken()); /*对读取的一行数据进行切分,先切到的肯定就是姓名,其次是数据*/ String name = tmp.nextToken(); String score = tmp.nextToken(); /*将分割好的姓名与对应的成绩放入到context对象写入内存传递给reduce处理*/ context.write(new Text(name),new IntWritable(Integer.parseInt(score))); } } } static class reducer extends Reducer<Text,IntWritable,Text,IntWritable>{ @Override protected void reduce(Text key, Iterable<IntWritable> values,Context context) throws IOException, InterruptedException { /*设置迭代器获取分数键值对*/ Iterator<IntWritable> iterator = values.iterator(); /*定义分数初始变量*/ int sum = 0; /*遍历这个迭代器中所有的值,hasNext方法是判定下一个是否还有值,如果有为true,无为false*/ while (iterator.hasNext()){ /*获取这个值*/ int v = iterator.next().get(); /*与上一个求和的值相加得到目前的总分,直到遍历完*/ sum += v; } /*文本内容不变,只需要改变这里的分数值即可,所以将总分放进去*/ context.write(key,new IntWritable(sum)); } } } |
- 点击运行主线程main方法,查看控制台有无map处理100%与reduce处理100%等成功信息总共写出字节44个。
- 进入终端输入 hdfs dfs -ls /data 查看是否有输出的out文件