Java/Web调用Hadoop进行MapReduce示例

原文章url:http://blog.csdn.net/csj941227/article/details/71786040

我们已经知道Hadoop能够通过Hadoop jar ***.jar input output的形式通过命令行来调用,那么如何将其封装成一个服务,让Java/Web来调用它?使得用户可以用方便的方式上传文件到Hadoop并进行处理,获得结果。首先,***.jar是一个Hadoop任务类的封装,我们可以在没有jar的情况下运行该类的main方法,将必要的参数传递给它。input 和output则将用户上传的文件使用Hadoop的JavaAPI put到Hadoop的文件系统中。然后再通过Hadoop的JavaAPI 从文件系统中取得结果文件。


搭建JavaWeb工程。本文使用Spring、SpringMVC、MyBatis框架, 当然,这不是重点,就算没有使用任何框架也能实现。

项目框架如下:


项目中使用到的jar包如下:


在Spring的配置文件中,加入

[html]  view plain  copy
  1. <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
  2.       <property name="defaultEncoding" value="utf-8" />  
  3.       <property name="maxUploadSize" value="10485760000" />  
  4.       <property name="maxInMemorySize" value="40960" />  
  5. </bean>  
使得项目支持文件上传。

新建一个login.jsp 点击登录后进入user/login

user/login中处理登录,登录成功后,【在Hadoop文件系统中创建用户文件夹】,然后跳转到console.jsp

[java]  view plain  copy
  1. package com.chenjie.controller;  
  2.   
  3.   
  4.   
  5. import java.io.IOException;  
  6.   
  7.   
  8.   
  9. import javax.annotation.Resource;  
  10.   
  11. import javax.servlet.http.HttpServletRequest;  
  12.   
  13. import javax.servlet.http.HttpServletResponse;  
  14.   
  15.   
  16.   
  17. import org.apache.hadoop.conf.Configuration;  
  18.   
  19. import org.apache.hadoop.fs.FileSystem;  
  20.   
  21. import org.apache.hadoop.fs.Path;  
  22.   
  23. import org.springframework.stereotype.Controller;  
  24.   
  25. import org.springframework.web.bind.annotation.RequestMapping;  
  26.   
  27.   
  28.   
  29. import com.chenjie.pojo.JsonResult;  
  30.   
  31. import com.chenjie.pojo.User;  
  32.   
  33. import com.chenjie.service.UserService;  
  34.   
  35. import com.chenjie.util.AppConfig;  
  36.   
  37. import com.google.gson.Gson;  
  38.   
  39.   
  40.   
  41. /** 
  42.  
  43.  * 用户请求控制器 
  44.  
  45.  *  
  46.  
  47.  * @author Chen 
  48.  
  49.  *  
  50.  
  51.  */  
  52.   
  53. @Controller  
  54.   
  55. // 声明当前类为控制器  
  56.   
  57. @RequestMapping("/user")  
  58.   
  59. // 声明当前类的路径  
  60.   
  61. public class UserController {  
  62.   
  63.     @Resource(name = "userService")  
  64.   
  65.     private UserService userService;// 由Spring容器注入一个UserService实例  
  66.   
  67.   
  68.   
  69.     /** 
  70.  
  71.      * 登录 
  72.  
  73.      *  
  74.  
  75.      * @param user 
  76.  
  77.      *            用户 
  78.  
  79.      * @param request 
  80.  
  81.      * @param response 
  82.  
  83.      * @throws IOException 
  84.  
  85.      */  
  86.   
  87.     @RequestMapping("/login")  
  88.   
  89.     // 声明当前方法的路径  
  90.   
  91.     public String login(User user, HttpServletRequest request,  
  92.   
  93.             HttpServletResponse response) throws IOException {  
  94.   
  95.         response.setContentType("application/json");// 设置响应内容格式为json  
  96.   
  97.         User result = userService.login(user);// 调用UserService的登录方法  
  98.   
  99.         request.getSession().setAttribute("user", result);  
  100.   
  101.         if (result != null) {  
  102.   
  103.             createHadoopFSFolder(result);  
  104.   
  105.             return "console";  
  106.   
  107.         }  
  108.   
  109.         return "login";  
  110.   
  111.     }  
  112.   
  113.   
  114.   
  115.       
  116.   
  117.   
  118.     public void createHadoopFSFolder(User user) throws IOException {  
  119.   
  120.         Configuration conf = new Configuration();  
  121.   
  122.         conf.addResource(new Path("/opt/hadoop-1.2.1/conf/core-site.xml"));  
  123.   
  124.         conf.addResource(new Path("/opt/hadoop-1.2.1/conf/hdfs-site.xml"));  
  125.   
  126.   
  127.   
  128.         FileSystem fileSystem = FileSystem.get(conf);  
  129.   
  130.         System.out.println(fileSystem.getUri());  
  131.   
  132.   
  133.   
  134.         Path file = new Path("/user/" + user.getU_username());  
  135.   
  136.         if (fileSystem.exists(file)) {  
  137.   
  138.             System.out.println("haddop hdfs user foler  exists.");  
  139.   
  140.             fileSystem.delete(file, true);  
  141.   
  142.             System.out.println("haddop hdfs user foler  delete success.");  
  143.   
  144.         }  
  145.   
  146.         fileSystem.mkdirs(file);  
  147.   
  148.         System.out.println("haddop hdfs user foler  creat success.");  
  149.   
  150.     }  
  151.   
  152.   
  153.   
  154. }  
console.jsp中进行文件上传和任务提交、


文件上传和任务提交:

[java]  view plain  copy
  1. package com.chenjie.controller;  
  2.   
  3. import java.io.File;  
  4. import java.io.IOException;  
  5. import java.net.InetSocketAddress;  
  6. import java.net.URI;  
  7. import java.util.ArrayList;  
  8. import java.util.Iterator;  
  9. import java.util.List;  
  10.   
  11. import javax.servlet.http.HttpServletRequest;  
  12. import javax.servlet.http.HttpServletResponse;  
  13.   
  14. import org.apache.hadoop.conf.Configuration;  
  15. import org.apache.hadoop.fs.FSDataInputStream;  
  16. import org.apache.hadoop.fs.FileSystem;  
  17. import org.apache.hadoop.fs.Path;  
  18. import org.apache.hadoop.mapred.JobClient;  
  19. import org.apache.hadoop.mapred.JobConf;  
  20. import org.apache.hadoop.mapred.JobID;  
  21. import org.apache.hadoop.mapred.JobStatus;  
  22. import org.apache.hadoop.mapred.RunningJob;  
  23. import org.springframework.stereotype.Controller;  
  24. import org.springframework.web.bind.annotation.RequestMapping;  
  25. import org.springframework.web.multipart.MultipartFile;  
  26. import org.springframework.web.multipart.MultipartHttpServletRequest;  
  27. import org.springframework.web.multipart.commons.CommonsMultipartResolver;  
  28.   
  29. import com.chenjie.pojo.User;  
  30. import com.chenjie.util.Utils;  
  31.   
  32. @Controller  
  33. // 声明当前类为控制器  
  34. @RequestMapping("/hadoop")  
  35. // 声明当前类的路径  
  36. public class HadoopController {  
  37.   
  38.     @RequestMapping("/upload")  
  39.     // 声明当前方法的路径  
  40.     //文件上传  
  41.     public String upload(HttpServletRequest request,  
  42.             HttpServletResponse response) throws IOException {  
  43.         List<String> fileList = (List<String>) request.getSession()  
  44.                 .getAttribute("fileList");//得到用户已上传文件列表  
  45.         if (fileList == null)  
  46.             fileList = new ArrayList<String>();//如果文件列表为空,则新建  
  47.         User user = (User) request.getSession().getAttribute("user");  
  48.         if (user == null)  
  49.             return "login";//如果用户未登录,则跳转登录页面  
  50.         CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(  
  51.                 request.getSession().getServletContext());//得到在Spring配置文件中注入的文件上传组件  
  52.         if (multipartResolver.isMultipart(request)) {//如果请求是文件请求  
  53.             MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;  
  54.   
  55.             Iterator<String> iter = multiRequest.getFileNames();//得到文件名迭代器  
  56.             while (iter.hasNext()) {  
  57.                 MultipartFile file = multiRequest.getFile((String) iter.next());  
  58.                 if (file != null) {  
  59.                     String fileName =  file.getOriginalFilename();  
  60.                     File folder = new File("/home/chenjie/CJHadoopOnline/"  
  61.                             + user.getU_username());  
  62.                     if (!folder.exists()) {  
  63.                         folder.mkdir();//如果文件不目录存在,则在服务器本地创建  
  64.                     }  
  65.                     String path = "/home/chenjie/CJHadoopOnline/"  
  66.                             + user.getU_username() + "/" + fileName;  
  67.   
  68.                     File localFile = new File(path);  
  69.   
  70.                     file.transferTo(localFile);//将上传文件拷贝到服务器本地目录  
  71.                     // fileList.add(path);  
  72.                 }  
  73.                 handleUploadFiles(user, fileList);//处理上传文件  
  74.             }  
  75.   
  76.         }  
  77.         request.getSession().setAttribute("fileList", fileList);//将上传文件列表保存在Session中  
  78.         return "console";//返回console.jsp继续上传文件  
  79.     }  
  80.   
  81.     @RequestMapping("/wordcount")  
  82.     //调用Hadoop进行mapreduce  
  83.     public void wordcount(HttpServletRequest request,  
  84.             HttpServletResponse response) {  
  85.         System.out.println("进入controller wordcount ");  
  86.         User user = (User) request.getSession().getAttribute("user");  
  87.         System.out.println(user);  
  88.         // if(user == null)  
  89.         // return "login";  
  90.         WordCount c = new WordCount();//新建单词统计任务  
  91.         String username = user.getU_username();  
  92.         String input = "hdfs://chenjie-virtual-machine:9000/user/" + username  
  93.                 + "/wordcountinput";//指定Hadoop文件系统的输入文件夹  
  94.         String output = "hdfs://chenjie-virtual-machine:9000/user/" + username  
  95.                 + "/wordcountoutput";//指定Hadoop文件系统的输出文件夹  
  96.         String reslt = output + "/part-r-00000";//默认输出文件  
  97.         try {  
  98.             Thread.sleep(3*1000);  
  99.             c.main(new String[] { input, output });//调用单词统计任务  
  100.             Configuration conf = new Configuration();//新建Hadoop配置  
  101.             conf.addResource(new Path("/opt/hadoop-1.2.1/conf/core-site.xml"));//添加Hadoop配置,找到Hadoop部署信息  
  102.             conf.addResource(new Path("/opt/hadoop-1.2.1/conf/hdfs-site.xml"));//Hadoop配置,找到文件系统  
  103.   
  104.             FileSystem fileSystem = FileSystem.get(conf);//得打文件系统  
  105.             Path file = new Path(reslt);//找到输出结果文件  
  106.             FSDataInputStream inStream = fileSystem.open(file);//打开  
  107.             URI uri = file.toUri();//得到输出文件路径  
  108.             System.out.println(uri);  
  109.             String data = null;  
  110.             while ((data = inStream.readLine()) != null) {  
  111.                 //System.out.println(data);  
  112.                 response.getOutputStream().println(data);//讲结果文件写回用户网页  
  113.             }  
  114. //          InputStream in = fileSystem.open(file);  
  115. //          OutputStream out = new FileOutputStream("result.txt");  
  116. //          IOUtils.copyBytes(in, out, 4096, true);  
  117.             inStream.close();  
  118.         } catch (Exception e) {  
  119.             System.err.println(e.getMessage());  
  120.         }  
  121.     }  
  122.   
  123.     @RequestMapping("/MapReduceStates")  
  124.     //得到MapReduce的状态  
  125.     public void mapreduce(HttpServletRequest request,  
  126.             HttpServletResponse response) {  
  127.         float[] progress=new float[2];  
  128.         try {  
  129.             Configuration conf1=new Configuration();  
  130.             conf1.set("mapred.job.tracker", Utils.JOBTRACKER);  
  131.               
  132.             JobStatus jobStatus  = Utils.getJobStatus(conf1);  
  133. //          while(!jobStatus.isJobComplete()){  
  134. //              progress = Utils.getMapReduceProgess(jobStatus);  
  135. //              response.getOutputStream().println("map:" + progress[0]  + "reduce:" + progress[1]);  
  136. //              Thread.sleep(1000);  
  137. //          }  
  138.             JobConf jc = new JobConf(conf1);  
  139.               
  140.             JobClient jobClient = new JobClient(jc);  
  141.             JobStatus[] jobsStatus = jobClient.getAllJobs();    
  142.             //这样就得到了一个JobStatus数组,随便取出一个元素取名叫jobStatus    
  143.             jobStatus = jobsStatus[0];    
  144.             JobID jobID = jobStatus.getJobID(); //通过JobStatus获取JobID    
  145.             RunningJob runningJob = jobClient.getJob(jobID);  //通过JobID得到RunningJob对象    
  146.             runningJob.getJobState();//可以获取作业状态,状态有五种,为JobStatus.Failed 、JobStatus.KILLED、JobStatus.PREP、JobStatus.RUNNING、JobStatus.SUCCEEDED    
  147.             jobStatus.getUsername();//可以获取运行作业的用户名。    
  148.             runningJob.getJobName();//可以获取作业名。    
  149.             jobStatus.getStartTime();//可以获取作业的开始时间,为UTC毫秒数。    
  150.             float map = runningJob.mapProgress();//可以获取Map阶段完成的比例,0~1,    
  151.             System.out.println("map=" + map);  
  152.             float reduce = runningJob.reduceProgress();//可以获取Reduce阶段完成的比例。  
  153.             System.out.println("reduce="+reduce);  
  154.             runningJob.getFailureInfo();//可以获取失败信息。    
  155.             runningJob.getCounters();//可以获取作业相关的计数器,计数器的内容和作业监控页面上看到的计数器的值一样。   
  156.               
  157.               
  158.         } catch (IOException e) {  
  159.             progress[0] = 0;  
  160.             progress[1] = 0;  
  161.         }  
  162.       
  163.         request.getSession().setAttribute("map", progress[0]);  
  164.         request.getSession().setAttribute("reduce", progress[1]);  
  165.     }  
  166.       
  167.     //处理文件上传  
  168.     public void handleUploadFiles(User user, List<String> fileList) {  
  169.         File folder = new File("/home/chenjie/CJHadoopOnline/"  
  170.                 + user.getU_username());  
  171.         if (!folder.exists())  
  172.             return;  
  173.         if (folder.isDirectory()) {  
  174.             File[] files = folder.listFiles();  
  175.             for (File file : files) {  
  176.                 System.out.println(file.getName());  
  177.                 try {  
  178.                     putFileToHadoopFSFolder(user, file, fileList);//将单个文件上传到Hadoop文件系统  
  179.                 } catch (IOException e) {  
  180.                     System.err.println(e.getMessage());  
  181.                 }  
  182.             }  
  183.         }  
  184.     }  
  185.   
  186.     //将单个文件上传到Hadoop文件系统  
  187.     private void putFileToHadoopFSFolder(User user, File file,  
  188.             List<String> fileList) throws IOException {  
  189.         Configuration conf = new Configuration();  
  190.         conf.addResource(new Path("/opt/hadoop-1.2.1/conf/core-site.xml"));  
  191.         conf.addResource(new Path("/opt/hadoop-1.2.1/conf/hdfs-site.xml"));  
  192.   
  193.         FileSystem fileSystem = FileSystem.get(conf);  
  194.         System.out.println(fileSystem.getUri());  
  195.   
  196.         Path localFile = new Path(file.getAbsolutePath());  
  197.         Path foler = new Path("/user/" + user.getU_username()  
  198.                 + "/wordcountinput");  
  199.         if (!fileSystem.exists(foler)) {  
  200.             fileSystem.mkdirs(foler);  
  201.         }  
  202.           
  203.         Path hadoopFile = new Path("/user/" + user.getU_username()  
  204.                 + "/wordcountinput/" + file.getName());  
  205. //      if (fileSystem.exists(hadoopFile)) {  
  206. //          System.out.println("File exists.");  
  207. //      } else {  
  208. //          fileSystem.mkdirs(hadoopFile);  
  209. //      }  
  210.         fileSystem.copyFromLocalFile(truetrue, localFile, hadoopFile);  
  211.         fileList.add(hadoopFile.toUri().toString());  
  212.   
  213.     }  
  214.   
  215. }  


启动Hadoop:


运行结果:

可以在任意平台下,登录该项目地址,上传文件,得到结果。






运行成功。




源代码:

https://github.com/tudoupaisimalingshu/CJHadoopOnline


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值