笔者因为毕业设计需要,搭建了一主机两从机的hadoop集群,皆为linux虚拟机。而window则是用于运行springmvc网站。进而结合hadoop与springmvc搭建一个系统。
1、MapReduce环境搭建
hadoop的安装是必不可少的,笔者用的是2.7.3版本的,搭建详细教程网上很多不再赘述。需要强调注意的点是:
(1)window与虚拟机都需要安装hadoop,除非window不进行mapreduce的开发
(2)在window中使用eclipse开发mapreduce,eclipse要安装相应的hadoop插件才能进行mapreduce开发。并且使用maven进行管理。(不用maven好像也行,但是没必要自找麻烦来管理包)
(3)eclipse可以连接hdfs直接查看其中的文件,但注意配置时相应的端口号(因此需要理解hadoop中的配置文件)与设置host文件中的主机名与ip地址映射(无论win还是linux)
2、MapReduce执行方式
(1)打成jar包,上传至虚拟机中,使用相关命令执行
(2)在eclipse中本地运行,主要用于mapreduce的调试。在运行时eclipse会让你选择“java应用程序”/“Run on Hadoop”,一般是选择后者,但笔者试过前者好像可以正常运行。
实现:在(1)的基础上在主函数加上
config.set("mapreduce.ramework.name","local");//设置为本地运行
关于文件的读取,既可以使用win本地,也可使用hdfs上的文件。具体代码可以自行查询,如果没有记错的话,应该是使用hdfs上的文件需要进行 config.set()来设置。
(3)客户端提交任务,服务器执行任务。简单来说就是window这边来控制启动,把作业远程提交至hadoop集群执行。在8088(根据设置会不同,但大部分是这个。)端口yarn网站中,可以看到job的执行状态,而本地运行是没有的。这个方法网上基本上说的都不清楚,解释几个问题
①基本实现,在(1)代码中合适位置加入以下代码(代码中具体的值根据需要修改)。并且在项目目录中加入hadoop集群的配置文件,具体位置网上大部分都说是src目录下,笔者也不知道项目目录会不会有区别。把src和src/main/java目录下都放了,以防万一。
·
config.set("fs.defaultFS", "hdfs://hadoop11:9000");//设置对应的
config.set("yarn.resourcemanager.hostname", "hadoop11");//设置resourcemanager
config.set("mapreduce.app-submission.cross-platform", "true");//跨平台问题
config.set("mapreduce.job.jar" , "C:\\DATA\\nlp.jar" );//确定jar包
job.setJarByClass(NLPmain.class);
job.setJar("C:\\DATA\\nlp.jar");//没有这句可能会导致找不到mapper/reduce类
②操作性问题
①中使用的jar包是mapreduce程序所在的jar包,也就是说上面的添加的代码也是包含在jar中的。若想直接执行的话,就是执行修改后的mapreduce程序。但笔者需要在网站中调用相应的函数,提交给客户端,因此将jar包作为第三方包引入项目,然后调用相关函数,便可直接执行。而不用把mapreduce代码引入。
在eclipse中调试mapreduce时,总是会时不时在本地运行,可以尝试右键项目——>Maven——>update project、或者clean+install,之后便会恢复正常。记得如果修改了代码,就需要重新打jar包,并且作为第三方包中的jar也要更新。
3、Error:Java heap speace 的解决方法
在解决上述问题后,程序终于跑起来后,发现程序好像卡住了,然后就报Error:Java heap speace的错误。首先虽然我的虚拟机性能低,但是肯定不是性能的问题。因为我在本地模式可以运行,而且数据集很小。所以锁定是hadoop集群配置的问题。这个问题网上有很多解决方法,我就不细说了。
但是按照网上的方法设置后,立马变成Container is running beyond virtual memory limits 的错误。简单说解释虚拟内存超出,这个也是配置的问题。可以在代码中加入下列配置,然后在Hadoop集群中也修改。这些网上都可以查到,不细说。
config.set("yarn.nodemanager.vmem-pmem-ratio", "3");//解决虚拟内存不足
config.set("mapred.map.child.java.opts","-Xmx1024m");//解决Error:java heap speca
重点来了!在进行一系列设置后还是报Container is running beyond virtual memory limits。我就很纳闷了,是哪里没有设置到吗?后面偶然看到某位博主说需要重启集群。我就进行重启,还是无效啊!最后我就干脆把虚拟机全部重启一遍,然后再次启动集群。接着就突然好了,我也没搞懂到底啥原因。这个问题卡了好几天了,最后莫名其妙解决了
在检查代码时、还发现mapper函数写的不够简洁,进行了重复计算。要充分利用setup()函数,提高代码效率。