001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package org.apache.hadoop.yarn.api.records; 020 021 import java.io.Serializable; 022 023 import org.apache.hadoop.classification.InterfaceAudience.Public; 024 import org.apache.hadoop.classification.InterfaceStability.Stable; 025 import org.apache.hadoop.yarn.api.ApplicationMasterProtocol; 026 import org.apache.hadoop.yarn.util.Records; 027 028 /** 029 * <p><code>ResourceRequest</code> represents the request made by an 030 * application to the <code>ResourceManager</code> to obtain various 031 * <code>Container</code> allocations.</p> 032 * 033 * <p>It includes: 034 * <ul> 035 * <li>{@link Priority} of the request.</li> 036 * <li> 037 * The <em>name</em> of the machine or rack on which the allocation is 038 * desired. A special value of <em>*</em> signifies that 039 * <em>any</em> host/rack is acceptable to the application. 040 * </li> 041 * <li>{@link Resource} required for each request.</li> 042 * <li> 043 * Number of containers, of above specifications, which are required 044 * by the application. 045 * </li> 046 * <li> 047 * A boolean <em>relaxLocality</em> flag, defaulting to <code>true</code>, 048 * which tells the <code>ResourceManager</code> if the application wants 049 * locality to be loose (i.e. allows fall-through to rack or <em>any</em>) 050 * or strict (i.e. specify hard constraint on resource allocation). 051 * </li> 052 * </ul> 053 * </p> 054 * 055 * @see Resource 056 * @see ApplicationMasterProtocol#allocate(org.apache.hadoop.yarn.api.protocolrecords.AllocateRequest) 057 */ 058 @Public 059 @Stable 060 public abstract class ResourceRequest implements Comparable<ResourceRequest> { 061 062 @Public 063 @Stable 064 public static ResourceRequest newInstance(Priority priority, String hostName, 065 Resource capability, int numContainers) { 066 return newInstance(priority, hostName, capability, numContainers, true); 067 } 068 069 @Public 070 @Stable 071 public static ResourceRequest newInstance(Priority priority, String hostName, 072 Resource capability, int numContainers, boolean relaxLocality) { 073 ResourceRequest request = Records.newRecord(ResourceRequest.class); 074 request.setPriority(priority); 075 request.setResourceName(hostName); 076 request.setCapability(capability); 077 request.setNumContainers(numContainers); 078 request.setRelaxLocality(relaxLocality); 079 return request; 080 } 081 082 @Public 083 @Stable 084 public static class ResourceRequestComparator implements 085 java.util.Comparator<ResourceRequest>, Serializable { 086 087 private static final long serialVersionUID = 1L; 088 089 @Override 090 public int compare(ResourceRequest r1, ResourceRequest r2) { 091 092 // Compare priority, host and capability 093 int ret = r1.getPriority().compareTo(r2.getPriority()); 094 if (ret == 0) { 095 String h1 = r1.getResourceName(); 096 String h2 = r2.getResourceName(); 097 ret = h1.compareTo(h2); 098 } 099 if (ret == 0) { 100 ret = r1.getCapability().compareTo(r2.getCapability()); 101 } 102 return ret; 103 } 104 } 105 106 /** 107 * The constant string representing no locality. 108 * It should be used by all references that want to pass an arbitrary host 109 * name in. 110 */ 111 public static final String ANY = "*"; 112 113 /** 114 * Check whether the given <em>host/rack</em> string represents an arbitrary 115 * host name. 116 * 117 * @param hostName <em>host/rack</em> on which the allocation is desired 118 * @return whether the given <em>host/rack</em> string represents an arbitrary 119 * host name 120 */ 121 @Public 122 @Stable 123 public static boolean isAnyLocation(String hostName) { 124 return ANY.equals(hostName); 125 } 126 127 /** 128 * Get the <code>Priority</code> of the request. 129 * @return <code>Priority</code> of the request 130 */ 131 @Public 132 @Stable 133 public abstract Priority getPriority(); 134 135 /** 136 * Set the <code>Priority</code> of the request 137 * @param priority <code>Priority</code> of the request 138 */ 139 @Public 140 @Stable 141 public abstract void setPriority(Priority priority); 142 143 /** 144 * Get the resource (e.g. <em>host/rack</em>) on which the allocation 145 * is desired. 146 * 147 * A special value of <em>*</em> signifies that <em>any</em> resource 148 * (host/rack) is acceptable. 149 * 150 * @return resource (e.g. <em>host/rack</em>) on which the allocation 151 * is desired 152 */ 153 @Public 154 @Stable 155 public abstract String getResourceName(); 156 157 /** 158 * Set the resource name (e.g. <em>host/rack</em>) on which the allocation 159 * is desired. 160 * 161 * A special value of <em>*</em> signifies that <em>any</em> resource name 162 * (e.g. host/rack) is acceptable. 163 * 164 * @param resourceName (e.g. <em>host/rack</em>) on which the 165 * allocation is desired 166 */ 167 @Public 168 @Stable 169 public abstract void setResourceName(String resourceName); 170 171 /** 172 * Get the <code>Resource</code> capability of the request. 173 * @return <code>Resource</code> capability of the request 174 */ 175 @Public 176 @Stable 177 public abstract Resource getCapability(); 178 179 /** 180 * Set the <code>Resource</code> capability of the request 181 * @param capability <code>Resource</code> capability of the request 182 */ 183 @Public 184 @Stable 185 public abstract void setCapability(Resource capability); 186 187 /** 188 * Get the number of containers required with the given specifications. 189 * @return number of containers required with the given specifications 190 */ 191 @Public 192 @Stable 193 public abstract int getNumContainers(); 194 195 /** 196 * Set the number of containers required with the given specifications 197 * @param numContainers number of containers required with the given 198 * specifications 199 */ 200 @Public 201 @Stable 202 public abstract void setNumContainers(int numContainers); 203 204 /** 205 * Get whether locality relaxation is enabled with this 206 * <code>ResourceRequest</code>. Defaults to true. 207 * 208 * @return whether locality relaxation is enabled with this 209 * <code>ResourceRequest</code>. 210 */ 211 @Public 212 @Stable 213 public abstract boolean getRelaxLocality(); 214 215 /** 216 * <p>For a request at a network hierarchy level, set whether locality can be relaxed 217 * to that level and beyond.<p> 218 * 219 * <p>If the flag is off on a rack-level <code>ResourceRequest</code>, 220 * containers at that request's priority will not be assigned to nodes on that 221 * request's rack unless requests specifically for those nodes have also been 222 * submitted.<p> 223 * 224 * <p>If the flag is off on an {@link ResourceRequest#ANY}-level 225 * <code>ResourceRequest</code>, containers at that request's priority will 226 * only be assigned on racks for which specific requests have also been 227 * submitted.<p> 228 * 229 * <p>For example, to request a container strictly on a specific node, the 230 * corresponding rack-level and any-level requests should have locality 231 * relaxation set to false. Similarly, to request a container strictly on a 232 * specific rack, the corresponding any-level request should have locality 233 * relaxation set to false.<p> 234 * 235 * @param relaxLocality whether locality relaxation is enabled with this 236 * <code>ResourceRequest</code>. 237 */ 238 @Public 239 @Stable 240 public abstract void setRelaxLocality(boolean relaxLocality); 241 242 @Override 243 public int hashCode() { 244 final int prime = 2153; 245 int result = 2459; 246 Resource capability = getCapability(); 247 String hostName = getResourceName(); 248 Priority priority = getPriority(); 249 result = 250 prime * result + ((capability == null) ? 0 : capability.hashCode()); 251 result = prime * result + ((hostName == null) ? 0 : hostName.hashCode()); 252 result = prime * result + getNumContainers(); 253 result = prime * result + ((priority == null) ? 0 : priority.hashCode()); 254 return result; 255 } 256 257 @Override 258 public boolean equals(Object obj) { 259 if (this == obj) 260 return true; 261 if (obj == null) 262 return false; 263 if (getClass() != obj.getClass()) 264 return false; 265 ResourceRequest other = (ResourceRequest) obj; 266 Resource capability = getCapability(); 267 if (capability == null) { 268 if (other.getCapability() != null) 269 return false; 270 } else if (!capability.equals(other.getCapability())) 271 return false; 272 String hostName = getResourceName(); 273 if (hostName == null) { 274 if (other.getResourceName() != null) 275 return false; 276 } else if (!hostName.equals(other.getResourceName())) 277 return false; 278 if (getNumContainers() != other.getNumContainers()) 279 return false; 280 Priority priority = getPriority(); 281 if (priority == null) { 282 if (other.getPriority() != null) 283 return false; 284 } else if (!priority.equals(other.getPriority())) 285 return false; 286 return true; 287 } 288 289 @Override 290 public int compareTo(ResourceRequest other) { 291 int priorityComparison = this.getPriority().compareTo(other.getPriority()); 292 if (priorityComparison == 0) { 293 int hostNameComparison = 294 this.getResourceName().compareTo(other.getResourceName()); 295 if (hostNameComparison == 0) { 296 int capabilityComparison = 297 this.getCapability().compareTo(other.getCapability()); 298 if (capabilityComparison == 0) { 299 int numContainersComparison = 300 this.getNumContainers() - other.getNumContainers(); 301 if (numContainersComparison == 0) { 302 return 0; 303 } else { 304 return numContainersComparison; 305 } 306 } else { 307 return capabilityComparison; 308 } 309 } else { 310 return hostNameComparison; 311 } 312 } else { 313 return priorityComparison; 314 } 315 } 316 }