实验三—MapReduce实验报告
一、实验目的
1.通过实验掌握基本的MapReduce安装,连接,开启,编程方法;
2.掌握用MapReduce解决一些常见的数据处理问题,包括数据去重、数据排序和数据挖掘等。
二、实验平台
已经配置完成的Hadoop伪分布式环境。
三、实验步骤
首先要先了解一下HDFS中的常用的命令
-mkdir 在HDFS创建目录 hdfs dfs -mkdir /data
-ls 查看当前目录 hdfs dfs -ls /
-ls -R 查看目录与子目录
-put 上传一个文件 hdfs dfs -put data.txt /data/input
-moveFromLocal 上传一个文件,会删除本地文件:ctrl + X
-copyFromLocal 上传一个文件,与put一样
-copyToLocal 下载文件 hdfs dfs -copyToLocal /data/input/data.txt
-get 下载文件 hdfs dfs -get /data/input/data.txt
-rm 删除文件 hdfs dfs -rm /data/input/data.txt -getmerge 将目录所有的文件先合并,再下载
-cp 拷 hdfs dfs -cp /data/input/data.txt /data/input/data01.txt
-mv 移动: hdfs dfs -mv /data/input/data.txt /data/input/data02.txt
-count 统计目录下的文件个数
-text、-cat 查看文件的内容 hdfs dfs -cat /data/input/data.txt
-balancer 平衡操作
然后在hadoop目录下创建一个文件夹,我的是/usr/local/hadoop/myapp,用于存放打包好的java jar文件
先在在hadoop的用户登录用户下建立一个HDFS用户目录
cd /usr/local/hadoop
./bin/hdfs dfs –mkdir –p /user/hadoop
在新建的目录下创建一个input目录,用于存放hadoop运行时需要输入的文件
./bin/hdfs dfs –mkdir /input
在创建一个output目录用于存放hadoop运行输出的文件
/bin/hdfs dfs –mkdir /output
在登录时的文件夹下创建一个data.txt,是本实验输入的文件
用命令./bin/hdfs dfs -put /home/hadoop/myLocalFile.txt input存放到刚才创建的input目录下,当然也可以不这样做
用./bin/hdfs dfs –ls input查看是否上传成功
接下来就编译代码文件
WordCountMapper.java
import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
public class WordCountMapper extends Mapper
@Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
/*
* key: 输入的key
* value: 数据 I love Beijing
* context: Map上下文
*/
String data= value.toString();
//分词
String[] words = data.split(" ");
//输出每个单词
for(String w:words){
context.write(new Text(w), new LongWritable(1));
}
}
}
WordCountReducer.java
import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
public class WordCountReducer extends Reducer
@Override
protected void reduce(Text k3, Iterable v3,Context context) throws IOException, InterruptedException {
//v3: 是一个集合,每个元素就是v2
long total = 0;
for(LongWritable l:v3){
total = total + l.get();
}
//输出
context.write(k3, new LongWritable(total));
}
}
WordCountMain.java
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class WordCountMain {
public static void main(String[] args) throws Exception {
//创建一个job = map + reduce
Configuration conf = new Configuration();
//创建一个Job
Job job = Job.getInstance(conf);
//指定任务的入口
job.setJarByClass(WordCountMain.class);
//指定job的mapper
job.setMapperClass(WordCountMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class);
//指定job的reducer
job.setReducerClass(WordCountReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);
//指定任务的输入和输出
FileInputFormat.setInputPaths(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
//提交任务
job.waitForCompletion(true);
}
}
可以先运行一下wordCountMain.java,看看有没有错误
这里有错误是因为没有输入文件
点击WordCount工程,选择Export…
选在java->JAR file->next
JAR file:为我的创建的myapp文件,命名为WordCount.jar,点击next。
接着点击next。
Main class:点击Browse…
选择本工程的主类所在文件,几点ok。
到myapp文件夹下看有没有打包成功,WordCount.jar就是对应的打包文件。
输入hadoop jar ./myapp/WordCount.jar …/hadoop/input/data.txt …/hadoop/output/wc
命令含义为执行文件夹myapp下的WordCount.jar 输入文件为…/hadoop/input/data.txt 文件输出到…/hadoop/output/wc,wc文件夹会在执行命令的时候自动创建。
看到上图就说明运行成功了,可输入./bin/hdfs dfs -ls output/wc看一下输出文件
可以看到生成了_ SUCCESS文件和part-r-00000文件,查看part-r-00000文件
看到结果了,说明确实是运行成功了
四、实验过程中遇到的问题及其解决办法
1.访问HDFS无权限
报错内容一般如下:
org.apache.hadoop.security.AccessControlException: Permission denied: user=root, access=WRITE, inode="":nutch:supergroup:rwxr-xr-x
报错原因:主要是由于HDFS的文件系统都是有用户和权限的,如果当前用户无权限则在使用该文件或文件夹的时候会报错。
解决方案:
解决方案:在yarn-site.xml中添加
yarn.resourcemanager.hostname hadoop 4.no job control 报错信息如下所示: Exception message: /bin/bash: line 0: fg: no job control Stack trace: ExitCodeException exitCode=1: /bin/bash: line 0: fg: no job control at org.apache.hadoop.util.Shell.runCommand(Shell.java:545) at org.apache.hadoop.util.Shell.run(Shell.java:456) ... 报错原因:由于我们使用Windows平台进行开发并添加MR任务,而hadoop部署在Linux平台上,故针对跨平台的job会报该错 解决方案:在mapred-site.xml中添加以下配置 设置为job提交允许跨平台 mapreduce.app-submission.cross-platform true 5.ClassNotFoundExceptionError: java.lang.RuntimeException: java.lang.ClassNotFoundException: Class hadoop.mr.WordCount$WCMapper not found
at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:2195)
at org.apache.hadoop.mapreduce.task.JobContextImpl.getMapperClass(JobContextImpl.java:186)
…
报错原因:这个还是比较难解释的,需要对hadoop的运行原理有一定的了解。具体可参考这篇文章 https://blog.csdn.net/qq_19648191/article/details/56684268
解决方案:在core-site.xml中设置如下配置:
解决办法:重新给hdfs文件系统赋予权限(可能会经常遇到这种问题,可执行同一种操作即可)bin/hdfs dfs -chmod -R 777 /
错误三:
HMaster启动之后立即又关闭
问题分析:可能是zookeeper不稳定造成的,
解决办法:停止zookeeper服务(bin/zkServer.sh stop zoo1.cfg bin/zkServer.sh stop zoo2.cfg bin/zkServer.sh stop zoo3.cfg ),再重新启动
错误四:
15/08/23 11:10:07 INFO mapreduce.JobSubmitter: Cleaning up the staging area file:/usr/local/hadoop/tmp/mapred/staging/thinkgamer1735608800/.staging/job_local1735608800_0001
Exception in thread “main” ExitCodeException exitCode=1: chmod: 无法访问"/usr/local/hadoop/tmp/mapred/staging/thinkgamer1735608800/.staging/job_local1735608800_0001": 没有那个文件或目录
问题分析:eclipse的配置文件缺少
解决办法:把配置hadoop时所修改的配置文件全部复制到src文件夹下
错误五:
Exception in thread “main” org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory hdfs://localhost:9000/thinkgamer/output already exists
问题分析:hdfs文件系统中的output文件夹已经存在
解决办法:删除即可(同时还可能出现找不到input目录的问题,此时注意检查input路径)
五、实验总结
通过本次实验,使我掌握基本的MapReduce编程方法;掌握用MapReduce解决一些常见的数据处理问题,包括数据去重、数据排序和数据挖掘等。短暂的大数据课程实验到此结束,但我知道对大数据的学习是没有尽头的。学习就是一个不断积累的过程,学到东西,或多或少,以另一种方式将它记录下来。
总结了一下排除上述问题的一个自己的心得:
感觉MapReduce任务离线调试真的坑比较多,很难定位到问题的所在,出现上述类问题主要有以下几点:1、集群环境处于不稳定状态;2、自己代码问题,可能是很小的一个细节;3、mapreduce任务配置参数的问题。
总之,遇到问题,不要怕麻烦,从程序的源头开始一步步排查,在排查的过程中不断总结,你的能力也就一步步在此过程中会慢慢提升。其实大多数人遇到问题最怕没有思路,不知道从哪里下手,这样会耗费大量时间。遇到问题能有个自己的思路是关键,我们首先得明白有哪些可能会导致出现这些问题,然后开始排查,这样处理问题才能有条不紊的进行下去,也是一种解决问题的比较好的方式。(踩得坑多了,路自然就平了,欢迎丢砖块)
越努力,越幸运,自己加油,陌生人,加油!!