Search in sources :

Example 6 with LlapServiceInstance

use of org.apache.hadoop.hive.llap.registry.LlapServiceInstance in project hive by apache.

the class LlapTaskSchedulerService method selectHost.

/**
 * @param request the list of preferred hosts. null implies any host
 * @return
 */
private SelectHostResult selectHost(TaskInfo request) {
    String[] requestedHosts = request.requestedHosts;
    String requestedHostsDebugStr = Arrays.toString(requestedHosts);
    if (LOG.isDebugEnabled()) {
        LOG.debug("selectingHost for task={} on hosts={}", request.task, requestedHostsDebugStr);
    }
    long schedulerAttemptTime = clock.getTime();
    // Read-lock. Not updating any stats at the moment.
    readLock.lock();
    try {
        boolean shouldDelayForLocality = request.shouldDelayForLocality(schedulerAttemptTime);
        LOG.debug("ShouldDelayForLocality={} for task={} on hosts={}", shouldDelayForLocality, request.task, requestedHostsDebugStr);
        if (requestedHosts != null && requestedHosts.length > 0) {
            int prefHostCount = -1;
            boolean requestedHostsWillBecomeAvailable = false;
            for (String host : requestedHosts) {
                prefHostCount++;
                // Pick the first host always. Weak attempt at cache affinity.
                Set<LlapServiceInstance> instances = activeInstances.getByHost(host);
                if (!instances.isEmpty()) {
                    for (LlapServiceInstance inst : instances) {
                        NodeInfo nodeInfo = instanceToNodeMap.get(inst.getWorkerIdentity());
                        if (nodeInfo != null) {
                            if (nodeInfo.canAcceptTask()) {
                                // Successfully scheduled.
                                LOG.info("Assigning {} when looking for {}." + " local=true FirstRequestedHost={}, #prefLocations={}", nodeInfo.toShortString(), host, (prefHostCount == 0), requestedHosts.length);
                                return new SelectHostResult(nodeInfo);
                            } else {
                                // The node cannot accept a task at the moment.
                                if (shouldDelayForLocality) {
                                    // Perform some checks on whether the node will become available or not.
                                    if (request.shouldForceLocality()) {
                                        requestedHostsWillBecomeAvailable = true;
                                    } else {
                                        if (nodeInfo.getEnableTime() > request.getLocalityDelayTimeout() && nodeInfo.isDisabled() && nodeInfo.hadCommFailure()) {
                                            LOG.debug("Host={} will not become available within requested timeout", nodeInfo);
                                        // This node will likely be activated after the task timeout expires.
                                        } else {
                                            // Worth waiting for the timeout.
                                            requestedHostsWillBecomeAvailable = true;
                                        }
                                    }
                                }
                            }
                        } else {
                            LOG.warn("Null NodeInfo when attempting to get host with worker {}, and host {}", inst, host);
                        // Leave requestedHostWillBecomeAvailable as is. If some other host is found - delay,
                        // else ends up allocating to a random host immediately.
                        }
                    }
                }
            }
            // Check if forcing the location is required.
            if (shouldDelayForLocality) {
                if (requestedHostsWillBecomeAvailable) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Delaying local allocation for [" + request.task + "] when trying to allocate on [" + requestedHostsDebugStr + "]" + ". ScheduleAttemptTime=" + schedulerAttemptTime + ", taskDelayTimeout=" + request.getLocalityDelayTimeout());
                    }
                    return SELECT_HOST_RESULT_DELAYED_LOCALITY;
                } else {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Skipping local allocation for [" + request.task + "] when trying to allocate on [" + requestedHostsDebugStr + "] since none of these hosts are part of the known list");
                    }
                }
            }
        }
        /* fall through - miss in locality or no locality-requested */
        Collection<LlapServiceInstance> instances = activeInstances.getAllInstancesOrdered(true);
        List<NodeInfo> allNodes = new ArrayList<>(instances.size());
        List<NodeInfo> activeNodesWithFreeSlots = new ArrayList<>();
        for (LlapServiceInstance inst : instances) {
            if (inst instanceof InactiveServiceInstance) {
                allNodes.add(null);
            } else {
                NodeInfo nodeInfo = instanceToNodeMap.get(inst.getWorkerIdentity());
                if (nodeInfo == null) {
                    allNodes.add(null);
                } else {
                    allNodes.add(nodeInfo);
                    if (nodeInfo.canAcceptTask()) {
                        activeNodesWithFreeSlots.add(nodeInfo);
                    }
                }
            }
        }
        if (allNodes.isEmpty()) {
            return SELECT_HOST_RESULT_DELAYED_RESOURCES;
        }
        // no locality-requested, randomly pick a node containing free slots
        if (requestedHosts == null || requestedHosts.length == 0) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("No-locality requested. Selecting a random host for task={}", request.task);
            }
            return randomSelection(activeNodesWithFreeSlots);
        }
        // miss in locality request, try picking consistent location with fallback to random selection
        final String firstRequestedHost = requestedHosts[0];
        int requestedHostIdx = -1;
        for (int i = 0; i < allNodes.size(); i++) {
            NodeInfo nodeInfo = allNodes.get(i);
            if (nodeInfo != null) {
                if (nodeInfo.getHost().equals(firstRequestedHost)) {
                    requestedHostIdx = i;
                    break;
                }
            }
        }
        // TODO: At this point we don't know the slot number of the requested host, so can't rollover to next available
        if (requestedHostIdx == -1) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Requested node [{}] in consistent order does not exist. Falling back to random selection for " + "request {}", firstRequestedHost, request);
            }
            return randomSelection(activeNodesWithFreeSlots);
        }
        // requested host is still alive but cannot accept task, pick the next available host in consistent order
        for (int i = 0; i < allNodes.size(); i++) {
            NodeInfo nodeInfo = allNodes.get((i + requestedHostIdx + 1) % allNodes.size());
            // next node in consistent order died or does not have free slots, rollover to next
            if (nodeInfo == null || !nodeInfo.canAcceptTask()) {
                continue;
            } else {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Assigning {} in consistent order when looking for first requested host, from #hosts={}," + " requestedHosts={}", nodeInfo.toShortString(), allNodes.size(), ((requestedHosts == null || requestedHosts.length == 0) ? "null" : requestedHostsDebugStr));
                }
                return new SelectHostResult(nodeInfo);
            }
        }
        return SELECT_HOST_RESULT_DELAYED_RESOURCES;
    } finally {
        readLock.unlock();
    }
}
Also used : ArrayList(java.util.ArrayList) LlapServiceInstance(org.apache.hadoop.hive.llap.registry.LlapServiceInstance) InactiveServiceInstance(org.apache.hadoop.hive.llap.registry.impl.InactiveServiceInstance)

Example 7 with LlapServiceInstance

use of org.apache.hadoop.hive.llap.registry.LlapServiceInstance in project hive by apache.

the class LlapTaskSchedulerService method getAvailableResources.

/**
 * The difference between this and getTotalResources() is that this only gives currently free
 * resource instances, while the other lists all the instances that may become available in a
 * while.
 */
@Override
public Resource getAvailableResources() {
    // need a state store eventually for current state & measure backoffs
    int memory = 0;
    int vcores = 0;
    readLock.lock();
    try {
        int numInstancesFound = 0;
        for (LlapServiceInstance inst : activeInstances.getAll()) {
            NodeInfo nodeInfo = instanceToNodeMap.get(inst.getWorkerIdentity());
            if (nodeInfo != null && !nodeInfo.isDisabled()) {
                Resource r = inst.getResource();
                memory += r.getMemory();
                vcores += r.getVirtualCores();
                numInstancesFound++;
            }
        }
        if (LOG.isDebugEnabled()) {
            LOG.debug("GetAvailableResources: numInstancesFound={}, totalMem={}, totalVcores={}", numInstancesFound, memory, vcores);
        }
    } finally {
        readLock.unlock();
    }
    return Resource.newInstance(memory, vcores);
}
Also used : Resource(org.apache.hadoop.yarn.api.records.Resource) LlapServiceInstance(org.apache.hadoop.hive.llap.registry.LlapServiceInstance)

Example 8 with LlapServiceInstance

use of org.apache.hadoop.hive.llap.registry.LlapServiceInstance in project hive by apache.

the class LlapTokenClient method getDelegationToken.

public Token<LlapTokenIdentifier> getDelegationToken(String appId) throws IOException {
    if (!UserGroupInformation.isSecurityEnabled())
        return null;
    Iterator<LlapServiceInstance> llaps = null;
    if (clientInstance == null) {
        assert client == null;
        llaps = getLlapServices(false).iterator();
        clientInstance = llaps.next();
    }
    ByteString tokenBytes = null;
    boolean hasRefreshed = false;
    while (true) {
        try {
            tokenBytes = getTokenBytes(appId);
            break;
        } catch (IOException | ServiceException ex) {
            LOG.error("Cannot get a token, trying a different instance", ex);
            client = null;
            clientInstance = null;
        }
        if (llaps == null || !llaps.hasNext()) {
            if (hasRefreshed) {
                // Only refresh once.
                throw new RuntimeException("Cannot find any LLAPs to get the token from");
            }
            llaps = getLlapServices(true).iterator();
            hasRefreshed = true;
        }
        clientInstance = llaps.next();
    }
    Token<LlapTokenIdentifier> token = extractToken(tokenBytes);
    if (LOG.isInfoEnabled()) {
        LOG.info("Obtained a LLAP delegation token from " + clientInstance + ": " + token);
    }
    return token;
}
Also used : LlapTokenIdentifier(org.apache.hadoop.hive.llap.security.LlapTokenIdentifier) ServiceException(com.google.protobuf.ServiceException) ByteString(com.google.protobuf.ByteString) LlapServiceInstance(org.apache.hadoop.hive.llap.registry.LlapServiceInstance) IOException(java.io.IOException)

Example 9 with LlapServiceInstance

use of org.apache.hadoop.hive.llap.registry.LlapServiceInstance in project hive by apache.

the class LlapZookeeperRegistryImpl method getAllInstancesOrdered.

// The real implementation for the instanceset... instanceset has its own copy of the
// ZK cache yet completely depends on the parent in every other aspect and is thus unneeded.
Collection<LlapServiceInstance> getAllInstancesOrdered(boolean consistentIndexes, PathChildrenCache instancesCache) {
    Map<String, Long> slotByWorker = new HashMap<String, Long>();
    Set<LlapServiceInstance> unsorted = Sets.newHashSet();
    for (ChildData childData : instancesCache.getCurrentData()) {
        if (childData == null)
            continue;
        byte[] data = childData.getData();
        if (data == null)
            continue;
        String nodeName = extractNodeName(childData);
        if (nodeName.startsWith(WORKER_PREFIX)) {
            LlapServiceInstance instances = getInstanceByPath(childData.getPath());
            if (instances != null) {
                unsorted.add(instances);
            }
        } else if (nodeName.startsWith(SLOT_PREFIX)) {
            slotByWorker.put(extractWorkerIdFromSlot(childData), Long.parseLong(nodeName.substring(SLOT_PREFIX.length())));
        } else {
            LOG.info("Ignoring unknown node {}", childData.getPath());
        }
    }
    TreeMap<Long, LlapServiceInstance> sorted = new TreeMap<>();
    long maxSlot = Long.MIN_VALUE;
    for (LlapServiceInstance worker : unsorted) {
        Long slot = slotByWorker.get(worker.getWorkerIdentity());
        if (slot == null) {
            LOG.info("Unknown slot for {}", worker.getWorkerIdentity());
            continue;
        }
        maxSlot = Math.max(maxSlot, slot);
        sorted.put(slot, worker);
    }
    if (consistentIndexes) {
        // Add dummy instances to all slots where LLAPs are MIA... I can haz insert_iterator?
        TreeMap<Long, LlapServiceInstance> dummies = new TreeMap<>();
        Iterator<Long> keyIter = sorted.keySet().iterator();
        long expected = 0;
        Long ts = null;
        while (keyIter.hasNext()) {
            Long slot = keyIter.next();
            assert slot >= expected;
            while (slot > expected) {
                if (ts == null) {
                    // Inactive nodes restart every call!
                    ts = System.nanoTime();
                }
                dummies.put(expected, new InactiveServiceInstance("inactive-" + expected + "-" + ts));
                ++expected;
            }
            ++expected;
        }
        sorted.putAll(dummies);
    }
    return sorted.values();
}
Also used : HashMap(java.util.HashMap) LlapServiceInstance(org.apache.hadoop.hive.llap.registry.LlapServiceInstance) TreeMap(java.util.TreeMap) ChildData(org.apache.curator.framework.recipes.cache.ChildData)

Example 10 with LlapServiceInstance

use of org.apache.hadoop.hive.llap.registry.LlapServiceInstance in project hive by apache.

the class Utils method getSplitLocationProvider.

public static SplitLocationProvider getSplitLocationProvider(Configuration conf, boolean useCacheAffinity, Logger LOG) throws IOException {
    boolean useCustomLocations = HiveConf.getVar(conf, HiveConf.ConfVars.HIVE_EXECUTION_MODE).equals("llap") && HiveConf.getBoolVar(conf, HiveConf.ConfVars.LLAP_CLIENT_CONSISTENT_SPLITS) && useCacheAffinity;
    SplitLocationProvider splitLocationProvider;
    LOG.info("SplitGenerator using llap affinitized locations: " + useCustomLocations);
    if (useCustomLocations) {
        LlapRegistryService serviceRegistry = LlapRegistryService.getClient(conf);
        LOG.info("Using LLAP instance " + serviceRegistry.getApplicationId());
        Collection<LlapServiceInstance> serviceInstances = serviceRegistry.getInstances().getAllInstancesOrdered(true);
        Preconditions.checkArgument(!serviceInstances.isEmpty(), "No running LLAP daemons! Please check LLAP service status and zookeeper configuration");
        ArrayList<String> locations = new ArrayList<>(serviceInstances.size());
        for (LlapServiceInstance serviceInstance : serviceInstances) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Adding " + serviceInstance.getWorkerIdentity() + " with hostname=" + serviceInstance.getHost() + " to list for split locations");
            }
            locations.add(serviceInstance.getHost());
        }
        splitLocationProvider = new HostAffinitySplitLocationProvider(locations);
    } else {
        splitLocationProvider = new SplitLocationProvider() {

            @Override
            public String[] getLocations(InputSplit split) throws IOException {
                if (split == null) {
                    return null;
                }
                String[] locations = split.getLocations();
                if (locations != null && locations.length == 1) {
                    if ("localhost".equals(locations[0])) {
                        return ArrayUtils.EMPTY_STRING_ARRAY;
                    }
                }
                return locations;
            }
        };
    }
    return splitLocationProvider;
}
Also used : ArrayList(java.util.ArrayList) LlapServiceInstance(org.apache.hadoop.hive.llap.registry.LlapServiceInstance) SplitLocationProvider(org.apache.hadoop.mapred.split.SplitLocationProvider) LlapRegistryService(org.apache.hadoop.hive.llap.registry.impl.LlapRegistryService) IOException(java.io.IOException) InputSplit(org.apache.hadoop.mapred.InputSplit)

Aggregations

LlapServiceInstance (org.apache.hadoop.hive.llap.registry.LlapServiceInstance)14 IOException (java.io.IOException)7 ByteString (com.google.protobuf.ByteString)5 ArrayList (java.util.ArrayList)2 InactiveServiceInstance (org.apache.hadoop.hive.llap.registry.impl.InactiveServiceInstance)2 LlapRegistryService (org.apache.hadoop.hive.llap.registry.impl.LlapRegistryService)2 LlapTokenIdentifier (org.apache.hadoop.hive.llap.security.LlapTokenIdentifier)2 Resource (org.apache.hadoop.yarn.api.records.Resource)2 ServiceException (com.google.protobuf.ServiceException)1 OutputStream (java.io.OutputStream)1 InetAddress (java.net.InetAddress)1 Socket (java.net.Socket)1 URISyntaxException (java.net.URISyntaxException)1 HashMap (java.util.HashMap)1 LinkedList (java.util.LinkedList)1 TreeMap (java.util.TreeMap)1 ChildData (org.apache.curator.framework.recipes.cache.ChildData)1 LlapInstance (org.apache.hadoop.hive.llap.cli.status.LlapStatusHelpers.LlapInstance)1 LlapOutputSocketInitMessage (org.apache.hadoop.hive.llap.daemon.rpc.LlapDaemonProtocolProtos.LlapOutputSocketInitMessage)1 SignableVertexSpec (org.apache.hadoop.hive.llap.daemon.rpc.LlapDaemonProtocolProtos.SignableVertexSpec)1