FairSchedulerServlet.java
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:12k
源码类别:

网格计算

开发平台:

Java

  1. /**
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. package org.apache.hadoop.mapred;
  19. import java.io.IOException;
  20. import java.io.PrintWriter;
  21. import java.text.DateFormat;
  22. import java.text.SimpleDateFormat;
  23. import java.util.ArrayList;
  24. import java.util.Arrays;
  25. import java.util.Collection;
  26. import java.util.Collections;
  27. import java.util.Comparator;
  28. import java.util.Date;
  29. import java.util.List;
  30. import javax.servlet.ServletContext;
  31. import javax.servlet.ServletException;
  32. import javax.servlet.http.HttpServlet;
  33. import javax.servlet.http.HttpServletRequest;
  34. import javax.servlet.http.HttpServletResponse;
  35. import org.apache.hadoop.mapred.FairScheduler.JobInfo;
  36. import org.apache.hadoop.util.StringUtils;
  37. /**
  38.  * Servlet for displaying fair scheduler information, installed at
  39.  * [job tracker URL]/scheduler when the {@link FairScheduler} is in use.
  40.  * 
  41.  * The main features are viewing each job's task count and fair share, ability
  42.  * to change job priorities and pools from the UI, and ability to switch the
  43.  * scheduler to FIFO mode without restarting the JobTracker if this is required
  44.  * for any reason.
  45.  * 
  46.  * There is also an "advanced" view for debugging that can be turned on by
  47.  * going to [job tracker URL]/scheduler?advanced.
  48.  */
  49. public class FairSchedulerServlet extends HttpServlet {
  50.   private static final long serialVersionUID = 9104070533067306659L;
  51.   private static final DateFormat DATE_FORMAT = 
  52.     new SimpleDateFormat("MMM dd, HH:mm");
  53.   
  54.   private FairScheduler scheduler;
  55.   private JobTracker jobTracker;
  56.   private static long lastId = 0; // Used to generate unique element IDs
  57.   @Override
  58.   public void init() throws ServletException {
  59.     super.init();
  60.     ServletContext servletContext = this.getServletContext();
  61.     this.scheduler = (FairScheduler) servletContext.getAttribute("scheduler");
  62.     this.jobTracker = (JobTracker) scheduler.taskTrackerManager;
  63.   }
  64.   
  65.   @Override
  66.   protected void doPost(HttpServletRequest req, HttpServletResponse resp)
  67.       throws ServletException, IOException {
  68.     doGet(req, resp); // Same handler for both GET and POST
  69.   }
  70.   
  71.   @Override
  72.   public void doGet(HttpServletRequest request, HttpServletResponse response)
  73.     throws ServletException, IOException {
  74.     // If the request has a set* param, handle that and redirect to the regular
  75.     // view page so that the user won't resubmit the data if they hit refresh.
  76.     boolean advancedView = request.getParameter("advanced") != null;
  77.     if (request.getParameter("setFifo") != null) {
  78.       scheduler.setUseFifo(request.getParameter("setFifo").equals("true"));
  79.       response.sendRedirect("/scheduler" + (advancedView ? "?advanced" : ""));
  80.       return;
  81.     }
  82.     if (request.getParameter("setPool") != null) {
  83.       Collection<JobInProgress> runningJobs = jobTracker.getRunningJobs();
  84.       PoolManager poolMgr = null;
  85.       synchronized (scheduler) {
  86.         poolMgr = scheduler.getPoolManager();
  87.       }
  88.       String pool = request.getParameter("setPool");
  89.       String jobId = request.getParameter("jobid");
  90.       for (JobInProgress job: runningJobs) {
  91.         if (job.getProfile().getJobID().toString().equals(jobId)) {
  92.           synchronized(scheduler){
  93.             poolMgr.setPool(job, pool);
  94.           }
  95.           scheduler.update();
  96.           break;
  97.         }
  98.       }      
  99.       response.sendRedirect("/scheduler" + (advancedView ? "?advanced" : ""));
  100.       return;
  101.     }
  102.     if (request.getParameter("setPriority") != null) {
  103.       Collection<JobInProgress> runningJobs = jobTracker.getRunningJobs();      
  104.       JobPriority priority = JobPriority.valueOf(request.getParameter(
  105.           "setPriority"));
  106.       String jobId = request.getParameter("jobid");
  107.       for (JobInProgress job: runningJobs) {
  108.         if (job.getProfile().getJobID().toString().equals(jobId)) {
  109.           job.setPriority(priority);
  110.           scheduler.update();
  111.           break;
  112.         }
  113.       }      
  114.       response.sendRedirect("/scheduler" + (advancedView ? "?advanced" : ""));
  115.       return;
  116.     }
  117.     // Print out the normal response
  118.     response.setContentType("text/html");
  119.     PrintWriter out = new PrintWriter(response.getOutputStream());
  120.     String hostname = StringUtils.simpleHostname(
  121.         jobTracker.getJobTrackerMachine());
  122.     out.print("<html><head>");
  123.     out.printf("<title>%s Job Scheduler Admininstration</title>n", hostname);
  124.     out.print("<link rel="stylesheet" type="text/css" " + 
  125.         "href="/static/hadoop.css">n");
  126.     out.print("</head><body>n");
  127.     out.printf("<h1><a href="/jobtracker.jsp">%s</a> " + 
  128.         "Job Scheduler Administration</h1>n", hostname);
  129.     showPools(out, advancedView);
  130.     showJobs(out, advancedView);
  131.     showAdminForm(out, advancedView);
  132.     out.print("</body></html>n");
  133.     out.close();
  134.   }
  135.   /**
  136.    * Print a view of pools to the given output writer.
  137.    */
  138.   private void showPools(PrintWriter out, boolean advancedView) {
  139.     synchronized(scheduler) {
  140.       PoolManager poolManager = scheduler.getPoolManager();
  141.       out.print("<h2>Pools</h2>n");
  142.       out.print("<table border="2" cellpadding="5" cellspacing="2">n");
  143.       out.print("<tr><th>Pool</th><th>Running Jobs</th>" + 
  144.           "<th>Min Maps</th><th>Min Reduces</th>" + 
  145.           "<th>Running Maps</th><th>Running Reduces</th></tr>n");
  146.       List<Pool> pools = new ArrayList<Pool>(poolManager.getPools());
  147.       Collections.sort(pools, new Comparator<Pool>() {
  148.         public int compare(Pool p1, Pool p2) {
  149.           if (p1.isDefaultPool())
  150.             return 1;
  151.           else if (p2.isDefaultPool())
  152.             return -1;
  153.           else return p1.getName().compareTo(p2.getName());
  154.         }});
  155.       for (Pool pool: pools) {
  156.         int runningMaps = 0;
  157.         int runningReduces = 0;
  158.         for (JobInProgress job: pool.getJobs()) {
  159.           JobInfo info = scheduler.infos.get(job);
  160.           if (info != null) {
  161.             runningMaps += info.runningMaps;
  162.             runningReduces += info.runningReduces;
  163.           }
  164.         }
  165.         out.print("<tr>n");
  166.         out.printf("<td>%s</td>n", pool.getName());
  167.         out.printf("<td>%s</td>n", pool.getJobs().size());
  168.         out.printf("<td>%s</td>n", poolManager.getAllocation(pool.getName(),
  169.             TaskType.MAP));
  170.         out.printf("<td>%s</td>n", poolManager.getAllocation(pool.getName(), 
  171.             TaskType.REDUCE));
  172.         out.printf("<td>%s</td>n", runningMaps);
  173.         out.printf("<td>%s</td>n", runningReduces);
  174.         out.print("</tr>n");
  175.       }
  176.       out.print("</table>n");
  177.     }
  178.   }
  179.   /**
  180.    * Print a view of running jobs to the given output writer.
  181.    */
  182.   private void showJobs(PrintWriter out, boolean advancedView) {
  183.     out.print("<h2>Running Jobs</h2>n");
  184.     out.print("<table border="2" cellpadding="5" cellspacing="2">n");
  185.     int colsPerTaskType = advancedView ? 6 : 3;
  186.     out.printf("<tr><th rowspan=2>Submitted</th>" + 
  187.         "<th rowspan=2>JobID</th>" +
  188.         "<th rowspan=2>User</th>" +
  189.         "<th rowspan=2>Name</th>" +
  190.         "<th rowspan=2>Pool</th>" +
  191.         "<th rowspan=2>Priority</th>" +
  192.         "<th colspan=%d>Maps</th>" +
  193.         "<th colspan=%d>Reduces</th>",
  194.         colsPerTaskType, colsPerTaskType);
  195.     out.print("</tr><tr>n");
  196.     out.print("<th>Finished</th><th>Running</th><th>Fair Share</th>" +
  197.         (advancedView ? "<th>Weight</th><th>Deficit</th><th>minMaps</th>" : ""));
  198.     out.print("<th>Finished</th><th>Running</th><th>Fair Share</th>" +
  199.         (advancedView ? "<th>Weight</th><th>Deficit</th><th>minReduces</th>" : ""));
  200.     out.print("</tr>n");
  201.     Collection<JobInProgress> runningJobs = jobTracker.getRunningJobs();
  202.     synchronized (scheduler) {
  203.       for (JobInProgress job: runningJobs) {
  204.         JobProfile profile = job.getProfile();
  205.         JobInfo info = scheduler.infos.get(job);
  206.         if (info == null) { // Job finished, but let's show 0's for info
  207.           info = new JobInfo();
  208.         }
  209.         out.print("<tr>n");
  210.         out.printf("<td>%s</td>n", DATE_FORMAT.format(
  211.             new Date(job.getStartTime())));
  212.         out.printf("<td><a href="jobdetails.jsp?jobid=%s">%s</a></td>",
  213.             profile.getJobID(), profile.getJobID());
  214.         out.printf("<td>%s</td>n", profile.getUser());
  215.         out.printf("<td>%s</td>n", profile.getJobName());
  216.         out.printf("<td>%s</td>n", generateSelect(
  217.             scheduler.getPoolManager().getPoolNames(),
  218.             scheduler.getPoolManager().getPoolName(job),
  219.             "/scheduler?setPool=<CHOICE>&jobid=" + profile.getJobID() +
  220.             (advancedView ? "&advanced" : "")));
  221.         out.printf("<td>%s</td>n", generateSelect(
  222.             Arrays.asList(new String[]
  223.                 {"VERY_LOW", "LOW", "NORMAL", "HIGH", "VERY_HIGH"}),
  224.             job.getPriority().toString(),
  225.             "/scheduler?setPriority=<CHOICE>&jobid=" + profile.getJobID() +
  226.             (advancedView ? "&advanced" : "")));
  227.         out.printf("<td>%d / %d</td><td>%d</td><td>%8.1f</td>n",
  228.             job.finishedMaps(), job.desiredMaps(), info.runningMaps,
  229.             info.mapFairShare);
  230.         if (advancedView) {
  231.           out.printf("<td>%8.1f</td>n", info.mapWeight);
  232.           out.printf("<td>%s</td>n", info.neededMaps > 0 ?
  233.               (info.mapDeficit / 1000) + "s" : "--");
  234.           out.printf("<td>%d</td>n", info.minMaps);
  235.         }
  236.         out.printf("<td>%d / %d</td><td>%d</td><td>%8.1f</td>n",
  237.             job.finishedReduces(), job.desiredReduces(), info.runningReduces,
  238.             info.reduceFairShare);
  239.         if (advancedView) {
  240.           out.printf("<td>%8.1f</td>n", info.reduceWeight);
  241.           out.printf("<td>%s</td>n", info.neededReduces > 0 ?
  242.               (info.reduceDeficit / 1000) + "s" : "--");
  243.           out.printf("<td>%d</td>n", info.minReduces);
  244.         }
  245.         out.print("</tr>n");
  246.       }
  247.     }
  248.     out.print("</table>n");
  249.   }
  250.   /**
  251.    * Generate a HTML select control with a given list of choices and a given
  252.    * option selected. When the selection is changed, take the user to the
  253.    * <code>submitUrl</code>. The <code>submitUrl</code> can be made to include
  254.    * the option selected -- the first occurrence of the substring
  255.    * <code>&lt;CHOICE&gt;</code> will be replaced by the option chosen.
  256.    */
  257.   private String generateSelect(Iterable<String> choices, 
  258.       String selectedChoice, String submitUrl) {
  259.     StringBuilder html = new StringBuilder();
  260.     String id = "select" + lastId++;
  261.     html.append("<select id="" + id + "" name="" + id + "" " + 
  262.         "onchange="window.location = '" + submitUrl + 
  263.         "'.replace('<CHOICE>', document.getElementById('" + id +
  264.         "').value);">n");
  265.     for (String choice: choices) {
  266.       html.append(String.format("<option value="%s"%s>%s</option>n",
  267.           choice, (choice.equals(selectedChoice) ? " selected" : ""), choice));
  268.     }
  269.     html.append("</select>n");
  270.     return html.toString();
  271.   }
  272.   /**
  273.    * Print the administration form at the bottom of the page, which currently
  274.    * only includes the button for switching between FIFO and Fair Scheduling.
  275.    */
  276.   private void showAdminForm(PrintWriter out, boolean advancedView) {
  277.     out.print("<h2>Scheduling Mode</h2>n");
  278.     String curMode = scheduler.getUseFifo() ? "FIFO" : "Fair Sharing";
  279.     String otherMode = scheduler.getUseFifo() ? "Fair Sharing" : "FIFO";
  280.     String advParam = advancedView ? "?advanced" : "";
  281.     out.printf("<form method="post" action="/scheduler%s">n", advParam);
  282.     out.printf("<p>The scheduler is currently using <b>%s mode</b>. " +
  283.         "<input type="submit" value="Switch to %s mode." " + 
  284.         "onclick="return confirm('Are you sure you want to change " +
  285.         "scheduling mode to %s?')" />n",
  286.         curMode, otherMode, otherMode);
  287.     out.printf("<input type="hidden" name="setFifo" value="%s" />",
  288.         !scheduler.getUseFifo());
  289.     out.print("</form>n");
  290.   }
  291. }