Search in sources :

Example 1 with ExceededCpuLimitException

use of com.facebook.presto.ExceededCpuLimitException in project presto by prestodb.

the class ClusterMemoryManager method process.

public synchronized void process(Iterable<QueryExecution> queries) {
    if (!enabled) {
        return;
    }
    boolean outOfMemory = isClusterOutOfMemory();
    if (!outOfMemory) {
        lastTimeNotOutOfMemory = System.nanoTime();
    }
    boolean queryKilled = false;
    long totalBytes = 0;
    for (QueryExecution query : queries) {
        long bytes = query.getTotalMemoryReservation();
        DataSize sessionMaxQueryMemory = getQueryMaxMemory(query.getSession());
        long queryMemoryLimit = Math.min(maxQueryMemory.toBytes(), sessionMaxQueryMemory.toBytes());
        totalBytes += bytes;
        if (resourceOvercommit(query.getSession()) && outOfMemory) {
            // If a query has requested resource overcommit, only kill it if the cluster has run out of memory
            DataSize memory = succinctBytes(bytes);
            query.fail(new PrestoException(CLUSTER_OUT_OF_MEMORY, format("The cluster is out of memory and %s=true, so this query was killed. It was using %s of memory", RESOURCE_OVERCOMMIT, memory)));
            queryKilled = true;
        }
        if (!resourceOvercommit(query.getSession()) && bytes > queryMemoryLimit) {
            DataSize maxMemory = succinctBytes(queryMemoryLimit);
            query.fail(exceededGlobalLimit(maxMemory));
            queryKilled = true;
        }
    }
    clusterMemoryUsageBytes.set(totalBytes);
    if (killOnOutOfMemory) {
        boolean shouldKillQuery = nanosSince(lastTimeNotOutOfMemory).compareTo(killOnOutOfMemoryDelay) > 0 && outOfMemory;
        boolean lastKilledQueryIsGone = (lastKilledQuery == null);
        if (!lastKilledQueryIsGone) {
            ClusterMemoryPool generalPool = pools.get(GENERAL_POOL);
            if (generalPool != null) {
                lastKilledQueryIsGone = generalPool.getQueryMemoryReservations().containsKey(lastKilledQuery);
            }
        }
        if (shouldKillQuery && lastKilledQueryIsGone && !queryKilled) {
            // Kill the biggest query in the general pool
            QueryExecution biggestQuery = null;
            long maxMemory = -1;
            for (QueryExecution query : queries) {
                long bytesUsed = query.getTotalMemoryReservation();
                if (bytesUsed > maxMemory && query.getMemoryPool().getId().equals(GENERAL_POOL)) {
                    biggestQuery = query;
                    maxMemory = bytesUsed;
                }
            }
            if (biggestQuery != null) {
                biggestQuery.fail(new PrestoException(CLUSTER_OUT_OF_MEMORY, "The cluster is out of memory, and your query was killed. Please try again in a few minutes."));
                queriesKilledDueToOutOfMemory.incrementAndGet();
                lastKilledQuery = biggestQuery.getQueryId();
            }
        }
    }
    Map<MemoryPoolId, Integer> countByPool = new HashMap<>();
    for (QueryExecution query : queries) {
        MemoryPoolId id = query.getMemoryPool().getId();
        countByPool.put(id, countByPool.getOrDefault(id, 0) + 1);
    }
    updatePools(countByPool);
    updateNodes(updateAssignments(queries));
    // check if CPU usage is over limit
    for (QueryExecution query : queries) {
        Duration cpuTime = query.getTotalCpuTime();
        Duration sessionLimit = getQueryMaxCpuTime(query.getSession());
        Duration limit = maxQueryCpuTime.compareTo(sessionLimit) < 0 ? maxQueryCpuTime : sessionLimit;
        if (cpuTime.compareTo(limit) > 0) {
            query.fail(new ExceededCpuLimitException(limit));
        }
    }
}
Also used : HashMap(java.util.HashMap) DataSize(io.airlift.units.DataSize) PrestoException(com.facebook.presto.spi.PrestoException) Duration(io.airlift.units.Duration) ExceededCpuLimitException(com.facebook.presto.ExceededCpuLimitException) QueryExecution(com.facebook.presto.execution.QueryExecution) MemoryPoolId(com.facebook.presto.spi.memory.MemoryPoolId)

Example 2 with ExceededCpuLimitException

use of com.facebook.presto.ExceededCpuLimitException in project presto by prestodb.

the class SqlQueryManager method enforceCpuLimits.

/**
 * Enforce query CPU time limits
 */
private void enforceCpuLimits() {
    for (QueryExecution query : queryTracker.getAllQueries()) {
        Duration cpuTime = query.getTotalCpuTime();
        QueryLimit<Duration> queryMaxCpuTimeLimit = getMinimum(createDurationLimit(maxQueryCpuTime, SYSTEM), query.getResourceGroupQueryLimits().flatMap(ResourceGroupQueryLimits::getCpuTimeLimit).map(rgLimit -> createDurationLimit(rgLimit, RESOURCE_GROUP)).orElse(null), createDurationLimit(getQueryMaxCpuTime(query.getSession()), QUERY));
        if (cpuTime.compareTo(queryMaxCpuTimeLimit.getLimit()) > 0) {
            query.fail(new ExceededCpuLimitException(queryMaxCpuTimeLimit.getLimit(), queryMaxCpuTimeLimit.getLimitSource().name()));
        }
    }
}
Also used : Duration(io.airlift.units.Duration) ExceededCpuLimitException(com.facebook.presto.ExceededCpuLimitException)

Aggregations

ExceededCpuLimitException (com.facebook.presto.ExceededCpuLimitException)2 Duration (io.airlift.units.Duration)2 QueryExecution (com.facebook.presto.execution.QueryExecution)1 PrestoException (com.facebook.presto.spi.PrestoException)1 MemoryPoolId (com.facebook.presto.spi.memory.MemoryPoolId)1 DataSize (io.airlift.units.DataSize)1 HashMap (java.util.HashMap)1