java web调用mapreduce算法-Day2&4(更新)

来源:互联网 发布:linux的service命令 编辑:程序博客网 时间:2024/05/16 15:17

 哈哈 在这千钧一发的时刻,居然好用了~时刻:22:37

1.第一个问题,由于昨天启动Tomcat次数过多,有很多日志留在/tmp目录下,可能还有别的原因,导致今天一来启动Tomcat就不行了,因为磁盘空间不足,后来师兄删了日志,并且告诉我记得自己删日志,还挪了11G磁盘空间给这个分区,这样就顺畅了~

2.MySQL报错:MySQL: Can't create/write to file '/tmp/#sql_3c6_0.MYI' (Errcode: 2)这种

https://stackoverflow.com/questions/11997012/mysql-cant-create-write-to-file-tmp-sql-3c6-0-myi-errcode-2-what-does

也是在stackoverflow的这个帖子下找到方法,那就是,重启MySQL哈哈,其中一个人说自己每个月遇到两三次这种情况,每次重启一下就好了,我就又麻烦师兄帮忙重启下MySQL,果然,OK了,原因大概是师兄删tmp目录的时候把什么东西也删掉了吧

3.然后就是昨天的查询慢的问题了,先说今天试MySQL查询,在小表上第一条是慢的,第二条之后就稳定了,但是在大数据集上,1G+就还是10min+今天,就先不管它了,昨天比较加上框架在集群上跑就卡在map11%了,今天调好了一跑还是卡在那;同时昨天和今天我都注意到一个问题,那就是启动的是localjobrunner,job的名称也是job_local***,那就说明这是本地模式啊,很可能因为这个所以才特别慢并且还占了很多磁盘空间,之后就baiduHadoop集群模式启动,我的代码通过调用类的main方法,就相当于eclipse直接运行main函数提交任务到Hadoop集群是一样的,一般我们使用命令行hadoop jar [jar-path][mainclass-name][input][output],这个命令行实现的就是将jar包提交到集群的各个节点上,所以用eclipse提交也必须完成这个功能,让集群需要知道这四个参数(命令行提供的),我的main函数代码如下:

Configuration conf = new Configuration();
conf.set("mapreduce.job.jar","/home/user/***.jar");  //change
conf.set("fs.defaultFS", "hdfs://master:9000/");          //change
conf.set("mapreduce.framework.name", "yarn");               //change
conf.set("yarn.resourcemanager.hostname", "master.cluster"); 
Job job = Job.getInstance(conf, "springboot");
job.setJarByClass(WordCount.class); 
 job.setMapperClass(TokenizerMapper.class);
 job.setReducerClass(IntSumReducer.class);
 job.setOutputKeyClass(LongWritable.class);
 job.setOutputValueClass(Text.class);
 FileInputFormat.addInputPath(job, new Path(args[0]));
 FileOutputFormat.setOutputPath(job, new Path(args[1]));
 job.waitForCompletion(true);


mapred.jar就是命令行提供的jar-path参数了,放在本地的那种;

fs.defaultFS这个就是HDFS的配置,想操作HDFS也要提供的,网上很多讲解了;

mapreduce.framework.name写死的,yarn模式就是集群模式;

yarn.resourcemanager.hostname也是在配置文件里的,去集群的配置文件看一看就好了;

关于命令行提供的[input][output]两个参数,是我调用这个main时指定的;[mainclass-name]这个参数,是我们打jar包时指定的(用eclipse的export打包,不是maven那种哦~)。



然鹅,和网上贴的代码不一样的就是,去掉了setjarbyclass,弄了一天终于跑起来了。因为我把springboot打成一个jar包ssh远程登录集群运行的工程,mapreduce.job.jar的路径是本地路径,所以我这里面涉及了两个jar!我实验了多种觉得mapreduce.job.jar参数应该是不能用jar包里的相对路径,所以jar不用打在工程里面(之前报ClassNotFound我想可能是运行的是jar就不能引用外部jar的class了?所以尝试把要跑的jar打进maven工程里,为了maven添加进本地jar包,我也卡了大半天,解决思路是把jar包install进本地仓库,然后dependency依赖加上就行,scope写runtime就打进去了),放在本地就行。所以我理解可能是由于setjarbyclass在conf设置mapreduce.job.jar后面,把之前的覆盖了,而mapreduce.job.jar才是我们要跑的jar,然后我就验证了一下我的想法,终于不报ClassNotFound了(幸运之神眷顾我啊……毕竟我也准备好了还有其它可能一个一个试呢,看见这“激动人心”的结果,真是幸运~)。(但是跑的很慢,卡在了数据库查询上,在本地模式跑也遇到过这种情况反正,重启大法反正就好了,可能文件什么的太多了又没空间了??)现在能跑起来的“环境”是:要运行的jar有setjarbyclass,springboot中调用的main里去掉。

http://www.aboutyun.com/thread-9366-1-1.html 讲的比较深,说是setjarbyclass方法就是找到class所属的jar以后赋值给mapreduce.job.jar,于是我就想到可能被覆盖了的问题。

因为我在本地运行main里和jar的main里都有setjarbyclass,但是可以运行并且结果正确,所以觉得setjarbyclass是问题根源的可能性很低,只是顺手试一试,没想到居然真的跟它有关系……

我想应该是放在集群上的时候main本身就在我打成的jar里,而且还有一个真正运行的jar,就两个了,而本地只有一个,毕竟本地的main在eclipse里运行所以不会有误会/覆盖吧,所以集群上的main才要去掉setjarbyclass。

因为我是远程ssh操作集群,所以把Mapreduce算法的jar包打好,放到集群我的用户目录下,不用上传到HDFS上啦,然后把我的springboot工程用maven build好出jar包,放到集群上,java -DServer.port=8090 -jar ***.jar启动,试着访问以下该方法,不仅Mapreduce成功,操作HDFS成功,数据也返回到浏览器上了~搞定~


说两个昨天落下忘讲了的小问题:

1.Java web调用Mapreduce的时候,main里面写的是System.exit(job.waitForcompletion(true)),这就导致什么呢,导致Mapreduce运行完JVM就关闭了,然后会导致Tomcat重启啥的而且重启会失败,具体我忘了,所以去掉System.exit就好~

2.“cd /”命令,师兄今天来我这帮我解决问题,我才知道还有这个目录呢,我之前以为只有我的主目录也就是“cd ~”访问到的那个,“cd /”就是root目录了吧,很厉害,想Hadoop_home还有我要定时清理的/tmp都在下面了,厉害厉害。


贴个图片纪念我这一晚的……推理秀!






原创粉丝点击