/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.mapred;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.mapreduce.TaskType;
/**
* {@link MemBasedLoadManager} implements {@link CapBasedLoadManager} for use by
* the {@link FairScheduler} that checks the available memory on tasktracker to
* determine whether to launch a task.
*
* Check the memory usage information of the Jobs and TaskTrackers to
* determine whether a task can be launched on a particular node.
*
* To use this class, set the following configurations
* 1. mapred.fairscheduler.loadmanager
* org.apache.hadoop.mapred.MemBasedLoadManager
* If this is not set up, FairScheduler will use the default LoadManager
* 2. mapred.membasedloadmanager.reservedvmem.mb
* mb of the desired reserved memory (not be used by tasks) on the machine
* If this is not set up, the default of 2GB will be used
*/
public class MemBasedLoadManager extends CapBasedLoadManager {
private long reservedPhysicalMemoryOnTT; // in mb
private static final long DEFAULT_RESERVED_PHYSICAL_MEMORY_ON_TT = 2 * 1024L;
public static final Log LOG = LogFactory.getLog(MemBasedLoadManager.class);
public static final String RESERVED_PHYSICAL_MEMORY_ON_TT_STRING =
"mapred.membasedloadmanager.reserved.physicalmemory.mb";
@Override
public void setConf(Configuration conf) {
super.setConf(conf);
setReservedPhysicalMemoryOnTT(conf.getLong(
RESERVED_PHYSICAL_MEMORY_ON_TT_STRING,
DEFAULT_RESERVED_PHYSICAL_MEMORY_ON_TT));
}
@Override
public void start() {
LOG.info("MemBasedLoadManager started");
}
@Override
public boolean canAssignMap(TaskTrackerStatus tracker,
int totalRunnableMaps, int totalMapSlots) {
return super.canAssignMap(tracker, totalRunnableMaps, totalMapSlots) &&
canAssign(tracker);
}
@Override
public boolean canAssignReduce(TaskTrackerStatus tracker,
int totalRunnableReduces, int totalReduceSlots) {
return super.canAssignReduce(tracker, totalRunnableReduces, totalReduceSlots)
&& canAssign(tracker);
}
@Override
public boolean canLaunchTask(TaskTrackerStatus tracker,
JobInProgress job, TaskType type) {
long taskMemory = (type == TaskType.MAP ? job.getMemoryForMapTask() :
job.getMemoryForReduceTask());
if (taskMemory == JobConf.DISABLED_MEMORY_LIMIT) {
return true;
}
taskMemory *= 1024 * 1024L; // Convert from MB to bytes
long availablePhysicalMemory =
tracker.getResourceStatus().getAvailablePhysicalMemory();
long reservedPhysicalMemory =
getReservedPhysicalMemoryOnTT() * 1024 * 1024L;
if (availablePhysicalMemory < reservedPhysicalMemory + taskMemory) {
String msg = String.format(
"Cannot assign tasks from %s to %s. Not enough memory." +
" Available:%s, Reserved:%s, Task:%s",
job.getJobID(),
tracker.getTrackerName(),
availablePhysicalMemory,
reservedPhysicalMemory,
taskMemory);
LOG.warn(msg);
return false;
}
return true;
}
boolean canAssign(TaskTrackerStatus tracker) {
long availablePhysicalMemory =
tracker.getResourceStatus().getAvailablePhysicalMemory();
long reservedPhysicalMemory =
getReservedPhysicalMemoryOnTT() * 1024 * 1024L;
if (availablePhysicalMemory < reservedPhysicalMemory) {
String msg = String.format(
"Cannot assign tasks to %s. Not enough memory." +
" Available:%s, Reserved %s", tracker.getTrackerName(),
availablePhysicalMemory, reservedPhysicalMemory);
LOG.warn(msg);
return false;
}
if (LOG.isDebugEnabled()) {
String msg = String.format(
"Can assign tasks to %s." +
" Available:%s, Reserved %s", tracker.getTrackerName(),
availablePhysicalMemory, reservedPhysicalMemory);
LOG.debug(msg);
}
return true;
}
/**
* Get reserved physical memory on TaskTracker in mb
* @return reservedPhysicalMemoryOnTT
*/
public long getReservedPhysicalMemoryOnTT() {
return reservedPhysicalMemoryOnTT;
}
/**
* Set reserved physical memory on TaskTracker in mb
* @param reservedPhyscialMemoryOnTT the reservedPhysicalMemoryOnTT to set
*/
public void setReservedPhysicalMemoryOnTT(long reservedPhysicalMemoryOnTT) {
this.reservedPhysicalMemoryOnTT = reservedPhysicalMemoryOnTT;
}
}