org.apache.hadoop.corona.Scheduler.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hadoop.corona.Scheduler.java

Source

/*
 * 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.corona;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.mapred.PoolFairnessCalculator;
import org.apache.hadoop.mapred.PoolMetadata;
import org.apache.hadoop.mapred.ResourceMetadata;
import org.apache.hadoop.metrics.MetricsRecord;

/**
 * Schedules the sessions with the various resources available.
 */
public class Scheduler {
    /** Class logger */
    public static final Log LOG = LogFactory.getLog(Scheduler.class);
    /** Map of resource type to particular scheduler */
    private final Map<ResourceType, SchedulerForType> schedulersForTypes;
    /** Reloadable configuration manager */
    private final ConfigManager configManager;
    /** Types of resources */
    private final Collection<ResourceType> types;
    /** Static configuration */
    private CoronaConf conf;

    /**
     * Primary constructor.
     *
     * @param nodeManager Manages the nodes and their resources
     * @param sessionManager Manages a collection of sessions
     * @param sessionNotifier Delivers notifications to sessions asynchronously
     * @param types Types of resources
     * @param metrics Cluster Manager metrics
     * @param conf Static configuration
     */
    public Scheduler(NodeManager nodeManager, SessionManager sessionManager, SessionNotifier sessionNotifier,
            Collection<ResourceType> types, ClusterManagerMetrics metrics, CoronaConf conf) {
        this(nodeManager, sessionManager, sessionNotifier, types, metrics, conf, new ConfigManager(types, conf));
    }

    /**
     * Used by unit test to fake the ConfigManager
     *
     * @param nodeManager Manages the nodes and their resources
     * @param sessionManager Manages a collection of sessions
     * @param sessionNotifier Delivers notifications to sessions asynchronously
     * @param types Types of resources
     * @param metrics Cluster Manager metrics.
     * @param configManager Manages the reloadable configuration
     * @param conf Static configuration
     */
    public Scheduler(NodeManager nodeManager, SessionManager sessionManager, SessionNotifier sessionNotifier,
            Collection<ResourceType> types, ClusterManagerMetrics metrics, CoronaConf conf,
            ConfigManager configManager) {
        this.configManager = configManager;
        this.schedulersForTypes = new EnumMap<ResourceType, SchedulerForType>(ResourceType.class);
        this.types = types;
        for (ResourceType type : types) {
            SchedulerForType schedulerForType = new SchedulerForType(type, sessionManager, sessionNotifier,
                    nodeManager, configManager, metrics, conf);
            schedulerForType.setDaemon(true);
            schedulerForType.setName("Scheduler-" + type);
            schedulersForTypes.put(type, schedulerForType);
        }
        this.conf = conf;
    }

    public ConfigManager getConfigManager() {
        return configManager;
    }

    /**
     * Add a session for scheduling.
     *
     * @param id Identifies the session
     * @param session Actual session to be scheduled
     */
    public void addSession(String id, Session session) {
        for (SchedulerForType scheduleThread : schedulersForTypes.values()) {
            scheduleThread.addSession(id, session);
        }
    }

    /**
     * Start the scheduling as well as the reloadable configuration manager.
     */
    public void start() {
        for (Thread schedulerForType : schedulersForTypes.values()) {
            LOG.info("Starting " + schedulerForType.getName());
            schedulerForType.start();
        }
        configManager.start();
    }

    public void setConf(CoronaConf conf) {
        this.conf = conf;
    }

    public CoronaConf getConf() {
        return conf;
    }

    /**
     * Stop the scheduling and disable the reloadable configuration manager.
     */
    public void close() {
        for (SchedulerForType scheduleThread : schedulersForTypes.values()) {
            scheduleThread.close();
        }
        for (Thread scheduleThread : schedulersForTypes.values()) {
            Utilities.waitThreadTermination(scheduleThread);
        }
        configManager.close();
    }

    /**
     * Notify the scheduler threads that the state has changed and
     * scheduling should occur.
     */
    public void notifyScheduler() {
        for (SchedulerForType scheduleThread : schedulersForTypes.values()) {
            synchronized (scheduleThread) {
                scheduleThread.notifyAll();
            }
        }
    }

    /**
     * Get an unmodifiable snapshot of the mapping from pool info to associated
     * metrics.
     *
     * @param type Type of resource.
     * @return Unmodifiable snapshot of mapping from pool info to metrics
     */
    public Map<PoolInfo, PoolInfoMetrics> getPoolInfoMetrics(ResourceType type) {
        return schedulersForTypes.get(type).getPoolInfoMetrics();
    }

    /**
     * Get a snapshot of the {@link PoolMetadata} objects for all the schedulers
     * for each resource type.  This is used for gathering metrics.
     *
     * @return List of snapshots for each pool and its resources
     */
    private List<PoolMetadata> getPoolMetadataList() {
        Map<String, PoolMetadata> poolNameMetadataMap = new HashMap<String, PoolMetadata>();
        for (Map.Entry<ResourceType, SchedulerForType> schedulerEntry : schedulersForTypes.entrySet()) {
            for (Map.Entry<PoolInfo, PoolInfoMetrics> poolEntry : schedulerEntry.getValue().getPoolInfoMetrics()
                    .entrySet()) {
                ResourceMetadata resourceMetadata = poolEntry.getValue().getResourceMetadata();
                // Ignore any invalid pool metrics
                if (resourceMetadata == null) {
                    continue;
                }
                String stringifiedPoolInfo = PoolInfo.createStringFromPoolInfo(poolEntry.getKey());
                PoolMetadata poolMetadata = poolNameMetadataMap.get(stringifiedPoolInfo);
                if (poolMetadata == null) {
                    poolMetadata = new PoolMetadata(stringifiedPoolInfo);
                    poolNameMetadataMap.put(stringifiedPoolInfo, poolMetadata);
                }
                poolMetadata.addResourceMetadata(schedulerEntry.getKey().toString(), resourceMetadata);
            }
        }
        return new ArrayList<PoolMetadata>(poolNameMetadataMap.values());
    }

    /**
     * Get a snapshot of the pool infos that is sorted.
     *
     * @return Sorted snapshot of the pool infos.
     */
    public List<PoolInfo> getPoolInfos() {
        Set<PoolInfo> poolInfos = new HashSet<PoolInfo>();
        for (ResourceType type : types) {
            poolInfos.addAll(getPoolInfoMetrics(type).keySet());
        }
        List<PoolInfo> result = new ArrayList<PoolInfo>();
        result.addAll(poolInfos);
        Collections.sort(result);
        return result;
    }

    /**
     * Submit the metrics.
     *
     * @param metricsRecord Where the metrics will be submitted
     */
    public void submitMetrics(MetricsRecord metricsRecord) {
        List<PoolMetadata> poolMetadatas = getPoolMetadataList();
        PoolFairnessCalculator.calculateFairness(poolMetadatas, metricsRecord);
        for (SchedulerForType scheduler : schedulersForTypes.values()) {
            scheduler.submitMetrics();
        }
    }
}