Search in sources :

Example 1 with StageExecutionState

use of com.facebook.presto.execution.StageExecutionState in project presto by prestodb.

the class LegacySqlQueryScheduler method schedule.

private void schedule() {
    if (!scheduling.compareAndSet(false, true)) {
        // still scheduling the previous batch of stages
        return;
    }
    List<StageExecutionAndScheduler> scheduledStageExecutions = new ArrayList<>();
    try (SetThreadName ignored = new SetThreadName("Query-%s", queryStateMachine.getQueryId())) {
        Set<StageId> completedStages = new HashSet<>();
        List<ExecutionSchedule> sectionExecutionSchedules = new LinkedList<>();
        while (!Thread.currentThread().isInterrupted()) {
            // remove finished section
            sectionExecutionSchedules.removeIf(ExecutionSchedule::isFinished);
            // try to pull more section that are ready to be run
            List<StreamingPlanSection> sectionsReadyForExecution = getSectionsReadyForExecution();
            // all finished
            if (sectionsReadyForExecution.isEmpty() && sectionExecutionSchedules.isEmpty()) {
                break;
            }
            List<List<StageExecutionAndScheduler>> sectionStageExecutions = getStageExecutions(sectionsReadyForExecution);
            sectionStageExecutions.forEach(scheduledStageExecutions::addAll);
            sectionStageExecutions.stream().map(executionInfos -> executionInfos.stream().collect(toImmutableList())).map(executionPolicy::createExecutionSchedule).forEach(sectionExecutionSchedules::add);
            while (sectionExecutionSchedules.stream().noneMatch(ExecutionSchedule::isFinished)) {
                List<ListenableFuture<?>> blockedStages = new ArrayList<>();
                List<StageExecutionAndScheduler> executionsToSchedule = sectionExecutionSchedules.stream().flatMap(schedule -> schedule.getStagesToSchedule().stream()).collect(toImmutableList());
                for (StageExecutionAndScheduler stageExecutionAndScheduler : executionsToSchedule) {
                    SqlStageExecution stageExecution = stageExecutionAndScheduler.getStageExecution();
                    StageId stageId = stageExecution.getStageExecutionId().getStageId();
                    stageExecution.beginScheduling();
                    // perform some scheduling work
                    ScheduleResult result = stageExecutionAndScheduler.getStageScheduler().schedule();
                    // Track leaf tasks if partial results are enabled
                    if (isPartialResultsEnabled(session) && stageExecutionAndScheduler.getStageExecution().getFragment().isLeaf()) {
                        for (RemoteTask task : result.getNewTasks()) {
                            partialResultQueryTaskTracker.trackTask(task);
                            task.addFinalTaskInfoListener(partialResultQueryTaskTracker::recordTaskFinish);
                        }
                    }
                    // modify parent and children based on the results of the scheduling
                    if (result.isFinished()) {
                        stageExecution.schedulingComplete();
                    } else if (!result.getBlocked().isDone()) {
                        blockedStages.add(result.getBlocked());
                    }
                    stageExecutionAndScheduler.getStageLinkage().processScheduleResults(stageExecution.getState(), result.getNewTasks());
                    schedulerStats.getSplitsScheduledPerIteration().add(result.getSplitsScheduled());
                    if (result.getBlockedReason().isPresent()) {
                        switch(result.getBlockedReason().get()) {
                            case WRITER_SCALING:
                                // no-op
                                break;
                            case WAITING_FOR_SOURCE:
                                schedulerStats.getWaitingForSource().update(1);
                                break;
                            case SPLIT_QUEUES_FULL:
                                schedulerStats.getSplitQueuesFull().update(1);
                                break;
                            case MIXED_SPLIT_QUEUES_FULL_AND_WAITING_FOR_SOURCE:
                                schedulerStats.getMixedSplitQueuesFullAndWaitingForSource().update(1);
                                break;
                            case NO_ACTIVE_DRIVER_GROUP:
                                schedulerStats.getNoActiveDriverGroup().update(1);
                                break;
                            default:
                                throw new UnsupportedOperationException("Unknown blocked reason: " + result.getBlockedReason().get());
                        }
                    }
                }
                // make sure to update stage linkage at least once per loop to catch async state changes (e.g., partial cancel)
                boolean stageFinishedExecution = false;
                for (StageExecutionAndScheduler stageExecutionInfo : scheduledStageExecutions) {
                    SqlStageExecution stageExecution = stageExecutionInfo.getStageExecution();
                    StageId stageId = stageExecution.getStageExecutionId().getStageId();
                    if (!completedStages.contains(stageId) && stageExecution.getState().isDone()) {
                        stageExecutionInfo.getStageLinkage().processScheduleResults(stageExecution.getState(), ImmutableSet.of());
                        completedStages.add(stageId);
                        stageFinishedExecution = true;
                    }
                }
                // if any stage has just finished execution try to pull more sections for scheduling
                if (stageFinishedExecution) {
                    break;
                }
                // wait for a state change and then schedule again
                if (!blockedStages.isEmpty()) {
                    try (TimeStat.BlockTimer timer = schedulerStats.getSleepTime().time()) {
                        tryGetFutureValue(whenAnyComplete(blockedStages), 1, SECONDS);
                    }
                    for (ListenableFuture<?> blockedStage : blockedStages) {
                        blockedStage.cancel(true);
                    }
                }
            }
        }
        for (StageExecutionAndScheduler stageExecutionInfo : scheduledStageExecutions) {
            StageExecutionState state = stageExecutionInfo.getStageExecution().getState();
            if (state != SCHEDULED && state != RUNNING && !state.isDone()) {
                throw new PrestoException(GENERIC_INTERNAL_ERROR, format("Scheduling is complete, but stage execution %s is in state %s", stageExecutionInfo.getStageExecution().getStageExecutionId(), state));
            }
        }
        scheduling.set(false);
        // Inform the tracker that task scheduling has completed
        partialResultQueryTaskTracker.completeTaskScheduling();
        if (!getSectionsReadyForExecution().isEmpty()) {
            startScheduling();
        }
    } catch (Throwable t) {
        scheduling.set(false);
        queryStateMachine.transitionToFailed(t);
        throw t;
    } finally {
        RuntimeException closeError = new RuntimeException();
        for (StageExecutionAndScheduler stageExecutionInfo : scheduledStageExecutions) {
            try {
                stageExecutionInfo.getStageScheduler().close();
            } catch (Throwable t) {
                queryStateMachine.transitionToFailed(t);
                // Self-suppression not permitted
                if (closeError != t) {
                    closeError.addSuppressed(t);
                }
            }
        }
        if (closeError.getSuppressed().length > 0) {
            throw closeError;
        }
    }
}
Also used : BasicStageExecutionStats(com.facebook.presto.execution.BasicStageExecutionStats) FunctionAndTypeManager(com.facebook.presto.metadata.FunctionAndTypeManager) WarningCollector(com.facebook.presto.spi.WarningCollector) OutputBuffers.createInitialEmptyOutputBuffers(com.facebook.presto.execution.buffer.OutputBuffers.createInitialEmptyOutputBuffers) Traverser.forTree(com.google.common.graph.Traverser.forTree) GENERIC_INTERNAL_ERROR(com.facebook.presto.spi.StandardErrorCode.GENERIC_INTERNAL_ERROR) SchedulingOrderVisitor.scheduleOrder(com.facebook.presto.sql.planner.SchedulingOrderVisitor.scheduleOrder) SystemSessionProperties.getMaxConcurrentMaterializations(com.facebook.presto.SystemSessionProperties.getMaxConcurrentMaterializations) OutputBufferId(com.facebook.presto.execution.buffer.OutputBuffers.OutputBufferId) SplitSourceFactory(com.facebook.presto.sql.planner.SplitSourceFactory) BROADCAST_PARTITION_ID(com.facebook.presto.execution.buffer.OutputBuffers.BROADCAST_PARTITION_ID) SqlStageExecution(com.facebook.presto.execution.SqlStageExecution) OutputBuffers.createDiscardingOutputBuffers(com.facebook.presto.execution.buffer.OutputBuffers.createDiscardingOutputBuffers) Duration(io.airlift.units.Duration) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) StageInfo(com.facebook.presto.execution.StageInfo) PlanFragment(com.facebook.presto.sql.planner.PlanFragment) Map(java.util.Map) MoreFutures.whenAnyComplete(com.facebook.airlift.concurrent.MoreFutures.whenAnyComplete) URI(java.net.URI) PlanPrinter.jsonFragmentPlan(com.facebook.presto.sql.planner.planPrinter.PlanPrinter.jsonFragmentPlan) PLANNED(com.facebook.presto.execution.StageExecutionState.PLANNED) RemoteTaskFactory(com.facebook.presto.execution.RemoteTaskFactory) ImmutableSet(com.google.common.collect.ImmutableSet) StageExecutionInfo(com.facebook.presto.execution.StageExecutionInfo) RUNNING(com.facebook.presto.execution.StageExecutionState.RUNNING) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) MILLISECONDS(java.util.concurrent.TimeUnit.MILLISECONDS) Collectors(java.util.stream.Collectors) String.format(java.lang.String.format) SqlParser(com.facebook.presto.sql.parser.SqlParser) DataSize(io.airlift.units.DataSize) List(java.util.List) MoreFutures.tryGetFutureValue(com.facebook.airlift.concurrent.MoreFutures.tryGetFutureValue) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) PlanVariableAllocator(com.facebook.presto.sql.planner.PlanVariableAllocator) FAILED(com.facebook.presto.execution.StageExecutionState.FAILED) Function.identity(java.util.function.Function.identity) Optional(java.util.Optional) StageId(com.facebook.presto.execution.StageId) Iterables(com.google.common.collect.Iterables) Logger(com.facebook.airlift.log.Logger) OutputBuffers(com.facebook.presto.execution.buffer.OutputBuffers) PlanOptimizer(com.facebook.presto.sql.planner.optimizations.PlanOptimizer) SystemSessionProperties.isPartialResultsEnabled(com.facebook.presto.SystemSessionProperties.isPartialResultsEnabled) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) SystemSessionProperties.getPartialResultsCompletionRatioThreshold(com.facebook.presto.SystemSessionProperties.getPartialResultsCompletionRatioThreshold) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) PrestoException(com.facebook.presto.spi.PrestoException) SCHEDULED(com.facebook.presto.execution.StageExecutionState.SCHEDULED) AtomicReference(java.util.concurrent.atomic.AtomicReference) SystemSessionProperties.isRuntimeOptimizerEnabled(com.facebook.presto.SystemSessionProperties.isRuntimeOptimizerEnabled) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) TimeStat(com.facebook.airlift.stats.TimeStat) SystemSessionProperties.getPartialResultsMaxExecutionTimeMultiplier(com.facebook.presto.SystemSessionProperties.getPartialResultsMaxExecutionTimeMultiplier) ABORTED(com.facebook.presto.execution.StageExecutionState.ABORTED) ImmutableList(com.google.common.collect.ImmutableList) PlanChecker(com.facebook.presto.sql.planner.sanity.PlanChecker) Objects.requireNonNull(java.util.Objects.requireNonNull) BasicStageExecutionStats.aggregateBasicStageStats(com.facebook.presto.execution.BasicStageExecutionStats.aggregateBasicStageStats) PlanFragmentId(com.facebook.presto.sql.planner.plan.PlanFragmentId) LinkedList(java.util.LinkedList) StageExecutionState(com.facebook.presto.execution.StageExecutionState) ExecutorService(java.util.concurrent.ExecutorService) CANCELED(com.facebook.presto.execution.StageExecutionState.CANCELED) SubPlan(com.facebook.presto.sql.planner.SubPlan) PlanNodeIdAllocator(com.facebook.presto.spi.plan.PlanNodeIdAllocator) SetThreadName(com.facebook.airlift.concurrent.SetThreadName) StreamingPlanSection.extractStreamingSections(com.facebook.presto.execution.scheduler.StreamingPlanSection.extractStreamingSections) Session(com.facebook.presto.Session) Iterables.getOnlyElement(com.google.common.collect.Iterables.getOnlyElement) LocationFactory(com.facebook.presto.execution.LocationFactory) HttpUriBuilder.uriBuilderFrom(com.facebook.airlift.http.client.HttpUriBuilder.uriBuilderFrom) Streams.stream(com.google.common.collect.Streams.stream) PlanNode(com.facebook.presto.spi.plan.PlanNode) RemoteTask(com.facebook.presto.execution.RemoteTask) TaskId(com.facebook.presto.execution.TaskId) ROOT_FRAGMENT_ID(com.facebook.presto.sql.planner.PlanFragmenter.ROOT_FRAGMENT_ID) FINISHED(com.facebook.presto.execution.StageExecutionState.FINISHED) QueryState(com.facebook.presto.execution.QueryState) QueryStateMachine(com.facebook.presto.execution.QueryStateMachine) Collections(java.util.Collections) SECONDS(java.util.concurrent.TimeUnit.SECONDS) PartialResultQueryManager(com.facebook.presto.execution.PartialResultQueryManager) Metadata(com.facebook.presto.metadata.Metadata) StageId(com.facebook.presto.execution.StageId) ArrayList(java.util.ArrayList) PrestoException(com.facebook.presto.spi.PrestoException) SqlStageExecution(com.facebook.presto.execution.SqlStageExecution) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) LinkedList(java.util.LinkedList) HashSet(java.util.HashSet) RemoteTask(com.facebook.presto.execution.RemoteTask) TimeStat(com.facebook.airlift.stats.TimeStat) LinkedList(java.util.LinkedList) SetThreadName(com.facebook.airlift.concurrent.SetThreadName) StageExecutionState(com.facebook.presto.execution.StageExecutionState) ListenableFuture(com.google.common.util.concurrent.ListenableFuture)

Example 2 with StageExecutionState

use of com.facebook.presto.execution.StageExecutionState in project presto by prestodb.

the class SqlQueryScheduler method schedule.

private void schedule() {
    if (!scheduling.compareAndSet(false, true)) {
        // still scheduling the previous batch of stages
        return;
    }
    List<StageExecutionAndScheduler> scheduledStageExecutions = new ArrayList<>();
    try (SetThreadName ignored = new SetThreadName("Query-%s", queryStateMachine.getQueryId())) {
        Set<StageId> completedStages = new HashSet<>();
        List<ExecutionSchedule> executionSchedules = new LinkedList<>();
        while (!Thread.currentThread().isInterrupted()) {
            // remove finished section
            executionSchedules.removeIf(ExecutionSchedule::isFinished);
            // try to pull more section that are ready to be run
            List<StreamingPlanSection> sectionsReadyForExecution = getSectionsReadyForExecution();
            // all finished
            if (sectionsReadyForExecution.isEmpty() && executionSchedules.isEmpty()) {
                break;
            }
            // Apply runtime CBO on the ready sections before creating SectionExecutions.
            List<SectionExecution> sectionExecutions = createStageExecutions(sectionsReadyForExecution.stream().map(this::tryCostBasedOptimize).collect(toImmutableList()));
            if (queryStateMachine.isDone()) {
                sectionExecutions.forEach(SectionExecution::abort);
                break;
            }
            sectionExecutions.forEach(sectionExecution -> scheduledStageExecutions.addAll(sectionExecution.getSectionStages()));
            sectionExecutions.stream().map(SectionExecution::getSectionStages).map(executionPolicy::createExecutionSchedule).forEach(executionSchedules::add);
            while (!executionSchedules.isEmpty() && executionSchedules.stream().noneMatch(ExecutionSchedule::isFinished)) {
                List<ListenableFuture<?>> blockedStages = new ArrayList<>();
                List<StageExecutionAndScheduler> executionsToSchedule = executionSchedules.stream().flatMap(schedule -> schedule.getStagesToSchedule().stream()).collect(toImmutableList());
                for (StageExecutionAndScheduler executionAndScheduler : executionsToSchedule) {
                    executionAndScheduler.getStageExecution().beginScheduling();
                    // perform some scheduling work
                    ScheduleResult result = executionAndScheduler.getStageScheduler().schedule();
                    // Track leaf tasks if partial results are enabled
                    if (isPartialResultsEnabled(session) && executionAndScheduler.getStageExecution().getFragment().isLeaf()) {
                        for (RemoteTask task : result.getNewTasks()) {
                            partialResultQueryTaskTracker.trackTask(task);
                            task.addFinalTaskInfoListener(partialResultQueryTaskTracker::recordTaskFinish);
                        }
                    }
                    // modify parent and children based on the results of the scheduling
                    if (result.isFinished()) {
                        executionAndScheduler.getStageExecution().schedulingComplete();
                    } else if (!result.getBlocked().isDone()) {
                        blockedStages.add(result.getBlocked());
                    }
                    executionAndScheduler.getStageLinkage().processScheduleResults(executionAndScheduler.getStageExecution().getState(), result.getNewTasks());
                    schedulerStats.getSplitsScheduledPerIteration().add(result.getSplitsScheduled());
                    if (result.getBlockedReason().isPresent()) {
                        switch(result.getBlockedReason().get()) {
                            case WRITER_SCALING:
                                // no-op
                                break;
                            case WAITING_FOR_SOURCE:
                                schedulerStats.getWaitingForSource().update(1);
                                break;
                            case SPLIT_QUEUES_FULL:
                                schedulerStats.getSplitQueuesFull().update(1);
                                break;
                            case MIXED_SPLIT_QUEUES_FULL_AND_WAITING_FOR_SOURCE:
                                schedulerStats.getMixedSplitQueuesFullAndWaitingForSource().update(1);
                                break;
                            case NO_ACTIVE_DRIVER_GROUP:
                                schedulerStats.getNoActiveDriverGroup().update(1);
                                break;
                            default:
                                throw new UnsupportedOperationException("Unknown blocked reason: " + result.getBlockedReason().get());
                        }
                    }
                }
                // make sure to update stage linkage at least once per loop to catch async state changes (e.g., partial cancel)
                boolean stageFinishedExecution = false;
                for (StageExecutionAndScheduler stageExecutionAndScheduler : scheduledStageExecutions) {
                    SqlStageExecution stageExecution = stageExecutionAndScheduler.getStageExecution();
                    StageId stageId = stageExecution.getStageExecutionId().getStageId();
                    if (!completedStages.contains(stageId) && stageExecution.getState().isDone()) {
                        stageExecutionAndScheduler.getStageLinkage().processScheduleResults(stageExecution.getState(), ImmutableSet.of());
                        completedStages.add(stageId);
                        stageFinishedExecution = true;
                    }
                }
                // if any stage has just finished execution try to pull more sections for scheduling
                if (stageFinishedExecution) {
                    break;
                }
                // wait for a state change and then schedule again
                if (!blockedStages.isEmpty()) {
                    try (TimeStat.BlockTimer timer = schedulerStats.getSleepTime().time()) {
                        tryGetFutureValue(whenAnyComplete(blockedStages), 1, SECONDS);
                    }
                    for (ListenableFuture<?> blockedStage : blockedStages) {
                        blockedStage.cancel(true);
                    }
                }
            }
        }
        for (StageExecutionAndScheduler stageExecutionAndScheduler : scheduledStageExecutions) {
            StageExecutionState state = stageExecutionAndScheduler.getStageExecution().getState();
            if (state != SCHEDULED && state != RUNNING && !state.isDone()) {
                throw new PrestoException(GENERIC_INTERNAL_ERROR, format("Scheduling is complete, but stage execution %s is in state %s", stageExecutionAndScheduler.getStageExecution().getStageExecutionId(), state));
            }
        }
        scheduling.set(false);
        // Inform the tracker that task scheduling has completed
        partialResultQueryTaskTracker.completeTaskScheduling();
        if (!getSectionsReadyForExecution().isEmpty()) {
            startScheduling();
        }
    } catch (Throwable t) {
        scheduling.set(false);
        queryStateMachine.transitionToFailed(t);
        throw t;
    } finally {
        RuntimeException closeError = new RuntimeException();
        for (StageExecutionAndScheduler stageExecutionAndScheduler : scheduledStageExecutions) {
            try {
                stageExecutionAndScheduler.getStageScheduler().close();
            } catch (Throwable t) {
                queryStateMachine.transitionToFailed(t);
                // Self-suppression not permitted
                if (closeError != t) {
                    closeError.addSuppressed(t);
                }
            }
        }
        if (closeError.getSuppressed().length > 0) {
            throw closeError;
        }
    }
}
Also used : BasicStageExecutionStats(com.facebook.presto.execution.BasicStageExecutionStats) WarningCollector(com.facebook.presto.spi.WarningCollector) ListMultimap(com.google.common.collect.ListMultimap) GENERIC_INTERNAL_ERROR(com.facebook.presto.spi.StandardErrorCode.GENERIC_INTERNAL_ERROR) SchedulingOrderVisitor.scheduleOrder(com.facebook.presto.sql.planner.SchedulingOrderVisitor.scheduleOrder) SystemSessionProperties.getMaxConcurrentMaterializations(com.facebook.presto.SystemSessionProperties.getMaxConcurrentMaterializations) SplitSourceFactory(com.facebook.presto.sql.planner.SplitSourceFactory) StageInfo(com.facebook.presto.execution.StageInfo) InternalNodeManager(com.facebook.presto.metadata.InternalNodeManager) Map(java.util.Map) PlanPrinter.jsonFragmentPlan(com.facebook.presto.sql.planner.planPrinter.PlanPrinter.jsonFragmentPlan) RemoteTaskFactory(com.facebook.presto.execution.RemoteTaskFactory) RUNNING(com.facebook.presto.execution.StageExecutionState.RUNNING) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Set(java.util.Set) MILLISECONDS(java.util.concurrent.TimeUnit.MILLISECONDS) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) Stream(java.util.stream.Stream) PlanVariableAllocator(com.facebook.presto.sql.planner.PlanVariableAllocator) ImmutableListMultimap(com.google.common.collect.ImmutableListMultimap) FAILED(com.facebook.presto.execution.StageExecutionState.FAILED) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) PlanOptimizer(com.facebook.presto.sql.planner.optimizations.PlanOptimizer) SystemSessionProperties.isRuntimeOptimizerEnabled(com.facebook.presto.SystemSessionProperties.isRuntimeOptimizerEnabled) ArrayList(java.util.ArrayList) PlanFragmentId(com.facebook.presto.sql.planner.plan.PlanFragmentId) CANCELED(com.facebook.presto.execution.StageExecutionState.CANCELED) PlanNodeIdAllocator(com.facebook.presto.spi.plan.PlanNodeIdAllocator) StreamingPlanSection.extractStreamingSections(com.facebook.presto.execution.scheduler.StreamingPlanSection.extractStreamingSections) Session(com.facebook.presto.Session) Iterables.getOnlyElement(com.google.common.collect.Iterables.getOnlyElement) LocationFactory(com.facebook.presto.execution.LocationFactory) HttpUriBuilder.uriBuilderFrom(com.facebook.airlift.http.client.HttpUriBuilder.uriBuilderFrom) Streams.stream(com.google.common.collect.Streams.stream) RemoteTask(com.facebook.presto.execution.RemoteTask) TaskId(com.facebook.presto.execution.TaskId) ROOT_FRAGMENT_ID(com.facebook.presto.sql.planner.PlanFragmenter.ROOT_FRAGMENT_ID) FINISHED(com.facebook.presto.execution.StageExecutionState.FINISHED) QueryState(com.facebook.presto.execution.QueryState) Metadata(com.facebook.presto.metadata.Metadata) FunctionAndTypeManager(com.facebook.presto.metadata.FunctionAndTypeManager) OutputBuffers.createInitialEmptyOutputBuffers(com.facebook.presto.execution.buffer.OutputBuffers.createInitialEmptyOutputBuffers) Traverser.forTree(com.google.common.graph.Traverser.forTree) OutputBufferId(com.facebook.presto.execution.buffer.OutputBuffers.OutputBufferId) BROADCAST_PARTITION_ID(com.facebook.presto.execution.buffer.OutputBuffers.BROADCAST_PARTITION_ID) SqlStageExecution(com.facebook.presto.execution.SqlStageExecution) OutputBuffers.createDiscardingOutputBuffers(com.facebook.presto.execution.buffer.OutputBuffers.createDiscardingOutputBuffers) Duration(io.airlift.units.Duration) PlanFragment(com.facebook.presto.sql.planner.PlanFragment) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) StageExecutionInfo.unscheduledExecutionInfo(com.facebook.presto.execution.StageExecutionInfo.unscheduledExecutionInfo) MoreFutures.whenAnyComplete(com.facebook.airlift.concurrent.MoreFutures.whenAnyComplete) URI(java.net.URI) ImmutableSet(com.google.common.collect.ImmutableSet) StageExecutionInfo(com.facebook.presto.execution.StageExecutionInfo) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Iterables.getLast(com.google.common.collect.Iterables.getLast) Collectors(java.util.stream.Collectors) String.format(java.lang.String.format) SqlParser(com.facebook.presto.sql.parser.SqlParser) Preconditions.checkState(com.google.common.base.Preconditions.checkState) DataSize(io.airlift.units.DataSize) List(java.util.List) MoreFutures.tryGetFutureValue(com.facebook.airlift.concurrent.MoreFutures.tryGetFutureValue) Optional(java.util.Optional) StageId(com.facebook.presto.execution.StageId) Logger(com.facebook.airlift.log.Logger) OutputBuffers(com.facebook.presto.execution.buffer.OutputBuffers) SystemSessionProperties.isPartialResultsEnabled(com.facebook.presto.SystemSessionProperties.isPartialResultsEnabled) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) SystemSessionProperties.getPartialResultsCompletionRatioThreshold(com.facebook.presto.SystemSessionProperties.getPartialResultsCompletionRatioThreshold) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) ExecutionFailureInfo(com.facebook.presto.execution.ExecutionFailureInfo) PrestoException(com.facebook.presto.spi.PrestoException) SCHEDULED(com.facebook.presto.execution.StageExecutionState.SCHEDULED) AtomicReference(java.util.concurrent.atomic.AtomicReference) HashSet(java.util.HashSet) TimeStat(com.facebook.airlift.stats.TimeStat) SystemSessionProperties.getPartialResultsMaxExecutionTimeMultiplier(com.facebook.presto.SystemSessionProperties.getPartialResultsMaxExecutionTimeMultiplier) ImmutableList(com.google.common.collect.ImmutableList) PlanChecker(com.facebook.presto.sql.planner.sanity.PlanChecker) Verify.verify(com.google.common.base.Verify.verify) Objects.requireNonNull(java.util.Objects.requireNonNull) BasicStageExecutionStats.aggregateBasicStageStats(com.facebook.presto.execution.BasicStageExecutionStats.aggregateBasicStageStats) LinkedList(java.util.LinkedList) StageExecutionState(com.facebook.presto.execution.StageExecutionState) ExecutorService(java.util.concurrent.ExecutorService) VerifyException(com.google.common.base.VerifyException) SubPlan(com.facebook.presto.sql.planner.SubPlan) SetThreadName(com.facebook.airlift.concurrent.SetThreadName) PlanNode(com.facebook.presto.spi.plan.PlanNode) RECOVERABLE_ERROR_CODES(com.facebook.presto.execution.SqlStageExecution.RECOVERABLE_ERROR_CODES) QueryStateMachine(com.facebook.presto.execution.QueryStateMachine) Collections(java.util.Collections) SystemSessionProperties.getMaxStageRetries(com.facebook.presto.SystemSessionProperties.getMaxStageRetries) SECONDS(java.util.concurrent.TimeUnit.SECONDS) PartialResultQueryManager(com.facebook.presto.execution.PartialResultQueryManager) StageId(com.facebook.presto.execution.StageId) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) PrestoException(com.facebook.presto.spi.PrestoException) SqlStageExecution(com.facebook.presto.execution.SqlStageExecution) HashSet(java.util.HashSet) RemoteTask(com.facebook.presto.execution.RemoteTask) TimeStat(com.facebook.airlift.stats.TimeStat) LinkedList(java.util.LinkedList) SetThreadName(com.facebook.airlift.concurrent.SetThreadName) StageExecutionState(com.facebook.presto.execution.StageExecutionState) ListenableFuture(com.google.common.util.concurrent.ListenableFuture)

Example 3 with StageExecutionState

use of com.facebook.presto.execution.StageExecutionState in project presto by prestodb.

the class SectionExecutionFactory method createStageScheduler.

private StageScheduler createStageScheduler(SplitSourceFactory splitSourceFactory, Session session, StreamingSubPlan plan, Function<PartitioningHandle, NodePartitionMap> partitioningCache, Optional<SqlStageExecution> parentStageExecution, StageId stageId, SqlStageExecution stageExecution, PartitioningHandle partitioningHandle, TableWriteInfo tableWriteInfo, Set<SqlStageExecution> childStageExecutions) {
    Map<PlanNodeId, SplitSource> splitSources = splitSourceFactory.createSplitSources(plan.getFragment(), session, tableWriteInfo);
    int maxTasksPerStage = getMaxTasksPerStage(session);
    if (partitioningHandle.equals(SOURCE_DISTRIBUTION)) {
        // nodes are selected dynamically based on the constraints of the splits and the system load
        Map.Entry<PlanNodeId, SplitSource> entry = getOnlyElement(splitSources.entrySet());
        PlanNodeId planNodeId = entry.getKey();
        SplitSource splitSource = entry.getValue();
        ConnectorId connectorId = splitSource.getConnectorId();
        if (isInternalSystemConnector(connectorId)) {
            connectorId = null;
        }
        NodeSelector nodeSelector = nodeScheduler.createNodeSelector(session, connectorId, maxTasksPerStage);
        SplitPlacementPolicy placementPolicy = new DynamicSplitPlacementPolicy(nodeSelector, stageExecution::getAllTasks);
        checkArgument(!plan.getFragment().getStageExecutionDescriptor().isStageGroupedExecution());
        return newSourcePartitionedSchedulerAsStageScheduler(stageExecution, planNodeId, splitSource, placementPolicy, splitBatchSize);
    } else if (partitioningHandle.equals(SCALED_WRITER_DISTRIBUTION)) {
        Supplier<Collection<TaskStatus>> sourceTasksProvider = () -> childStageExecutions.stream().map(SqlStageExecution::getAllTasks).flatMap(Collection::stream).map(RemoteTask::getTaskStatus).collect(toList());
        Supplier<Collection<TaskStatus>> writerTasksProvider = () -> stageExecution.getAllTasks().stream().map(RemoteTask::getTaskStatus).collect(toList());
        ScaledWriterScheduler scheduler = new ScaledWriterScheduler(stageExecution, sourceTasksProvider, writerTasksProvider, nodeScheduler.createNodeSelector(session, null), scheduledExecutor, getWriterMinSize(session), isOptimizedScaleWriterProducerBuffer(session));
        whenAllStages(childStageExecutions, StageExecutionState::isDone).addListener(scheduler::finish, directExecutor());
        return scheduler;
    } else {
        if (!splitSources.isEmpty()) {
            // contains local source
            List<PlanNodeId> schedulingOrder = plan.getFragment().getTableScanSchedulingOrder();
            ConnectorId connectorId = partitioningHandle.getConnectorId().orElseThrow(IllegalStateException::new);
            List<ConnectorPartitionHandle> connectorPartitionHandles;
            boolean groupedExecutionForStage = plan.getFragment().getStageExecutionDescriptor().isStageGroupedExecution();
            if (groupedExecutionForStage) {
                connectorPartitionHandles = nodePartitioningManager.listPartitionHandles(session, partitioningHandle);
                checkState(!ImmutableList.of(NOT_PARTITIONED).equals(connectorPartitionHandles));
            } else {
                connectorPartitionHandles = ImmutableList.of(NOT_PARTITIONED);
            }
            BucketNodeMap bucketNodeMap;
            List<InternalNode> stageNodeList;
            if (plan.getFragment().getRemoteSourceNodes().stream().allMatch(node -> node.getExchangeType() == REPLICATE)) {
                // no non-replicated remote source
                boolean dynamicLifespanSchedule = plan.getFragment().getStageExecutionDescriptor().isDynamicLifespanSchedule();
                bucketNodeMap = nodePartitioningManager.getBucketNodeMap(session, partitioningHandle, dynamicLifespanSchedule);
                // verify execution is consistent with planner's decision on dynamic lifespan schedule
                verify(bucketNodeMap.isDynamic() == dynamicLifespanSchedule);
                if (bucketNodeMap.hasInitialMap()) {
                    stageNodeList = bucketNodeMap.getBucketToNode().get().stream().distinct().collect(toImmutableList());
                } else {
                    stageNodeList = new ArrayList<>(nodeScheduler.createNodeSelector(session, connectorId).selectRandomNodes(maxTasksPerStage));
                }
            } else {
                // cannot use dynamic lifespan schedule
                verify(!plan.getFragment().getStageExecutionDescriptor().isDynamicLifespanSchedule());
                // remote source requires nodePartitionMap
                NodePartitionMap nodePartitionMap = partitioningCache.apply(plan.getFragment().getPartitioning());
                if (groupedExecutionForStage) {
                    checkState(connectorPartitionHandles.size() == nodePartitionMap.getBucketToPartition().length);
                }
                stageNodeList = nodePartitionMap.getPartitionToNode();
                bucketNodeMap = nodePartitionMap.asBucketNodeMap();
            }
            FixedSourcePartitionedScheduler fixedSourcePartitionedScheduler = new FixedSourcePartitionedScheduler(stageExecution, splitSources, plan.getFragment().getStageExecutionDescriptor(), schedulingOrder, stageNodeList, bucketNodeMap, splitBatchSize, getConcurrentLifespansPerNode(session), nodeScheduler.createNodeSelector(session, connectorId), connectorPartitionHandles);
            if (plan.getFragment().getStageExecutionDescriptor().isRecoverableGroupedExecution()) {
                stageExecution.registerStageTaskRecoveryCallback(taskId -> {
                    checkArgument(taskId.getStageExecutionId().getStageId().equals(stageId), "The task did not execute this stage");
                    checkArgument(parentStageExecution.isPresent(), "Parent stage execution must exist");
                    checkArgument(parentStageExecution.get().getAllTasks().size() == 1, "Parent stage should only have one task for recoverable grouped execution");
                    parentStageExecution.get().removeRemoteSourceIfSingleTaskStage(taskId);
                    fixedSourcePartitionedScheduler.recover(taskId);
                });
            }
            return fixedSourcePartitionedScheduler;
        } else {
            // all sources are remote
            NodePartitionMap nodePartitionMap = partitioningCache.apply(plan.getFragment().getPartitioning());
            List<InternalNode> partitionToNode = nodePartitionMap.getPartitionToNode();
            // todo this should asynchronously wait a standard timeout period before failing
            checkCondition(!partitionToNode.isEmpty(), NO_NODES_AVAILABLE, "No worker nodes available");
            return new FixedCountScheduler(stageExecution, partitionToNode);
        }
    }
}
Also used : NodeTaskMap(com.facebook.presto.execution.NodeTaskMap) TaskStatus(com.facebook.presto.execution.TaskStatus) ForScheduler(com.facebook.presto.operator.ForScheduler) RemoteSourceNode(com.facebook.presto.sql.planner.plan.RemoteSourceNode) REPLICATE(com.facebook.presto.sql.planner.plan.ExchangeNode.Type.REPLICATE) SplitSourceFactory(com.facebook.presto.sql.planner.SplitSourceFactory) SettableFuture(com.google.common.util.concurrent.SettableFuture) SqlStageExecution(com.facebook.presto.execution.SqlStageExecution) NOT_PARTITIONED(com.facebook.presto.spi.connector.NotPartitionedPartitionHandle.NOT_PARTITIONED) SqlStageExecution.createSqlStageExecution(com.facebook.presto.execution.SqlStageExecution.createSqlStageExecution) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Map(java.util.Map) SystemSessionProperties.getConcurrentLifespansPerNode(com.facebook.presto.SystemSessionProperties.getConcurrentLifespansPerNode) SystemSessionProperties.isOptimizedScaleWriterProducerBuffer(com.facebook.presto.SystemSessionProperties.isOptimizedScaleWriterProducerBuffer) QueryManagerConfig(com.facebook.presto.execution.QueryManagerConfig) Collectors.toSet(java.util.stream.Collectors.toSet) SplitSource(com.facebook.presto.split.SplitSource) RemoteTaskFactory(com.facebook.presto.execution.RemoteTaskFactory) ImmutableSet(com.google.common.collect.ImmutableSet) Predicate(java.util.function.Predicate) SystemSessionProperties.getWriterMinSize(com.facebook.presto.SystemSessionProperties.getWriterMinSize) Collection(java.util.Collection) TableWriteInfo.createTableWriteInfo(com.facebook.presto.execution.scheduler.TableWriteInfo.createTableWriteInfo) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Set(java.util.Set) NO_NODES_AVAILABLE(com.facebook.presto.spi.StandardErrorCode.NO_NODES_AVAILABLE) Iterables.getLast(com.google.common.collect.Iterables.getLast) NodeSelector(com.facebook.presto.execution.scheduler.nodeSelection.NodeSelector) SOURCE_DISTRIBUTION(com.facebook.presto.sql.planner.SystemPartitioningHandle.SOURCE_DISTRIBUTION) SourcePartitionedScheduler.newSourcePartitionedSchedulerAsStageScheduler(com.facebook.presto.execution.scheduler.SourcePartitionedScheduler.newSourcePartitionedSchedulerAsStageScheduler) Preconditions.checkState(com.google.common.base.Preconditions.checkState) MoreExecutors.directExecutor(com.google.common.util.concurrent.MoreExecutors.directExecutor) List(java.util.List) Optional(java.util.Optional) StageExecutionId(com.facebook.presto.execution.StageExecutionId) ConnectorId(com.facebook.presto.spi.ConnectorId) ConnectorId.isInternalSystemConnector(com.facebook.presto.spi.ConnectorId.isInternalSystemConnector) PlanNodeId(com.facebook.presto.spi.plan.PlanNodeId) StageId(com.facebook.presto.execution.StageId) OutputBuffers(com.facebook.presto.execution.buffer.OutputBuffers) ConnectorPartitionHandle(com.facebook.presto.spi.connector.ConnectorPartitionHandle) NodePartitionMap(com.facebook.presto.sql.planner.NodePartitionMap) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) HashMap(java.util.HashMap) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) Inject(javax.inject.Inject) ImmutableList(com.google.common.collect.ImmutableList) Verify.verify(com.google.common.base.Verify.verify) Objects.requireNonNull(java.util.Objects.requireNonNull) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) PlanFragmentId(com.facebook.presto.sql.planner.plan.PlanFragmentId) SystemSessionProperties.getMaxTasksPerStage(com.facebook.presto.SystemSessionProperties.getMaxTasksPerStage) StageExecutionState(com.facebook.presto.execution.StageExecutionState) ExecutorService(java.util.concurrent.ExecutorService) Failures.checkCondition(com.facebook.presto.util.Failures.checkCondition) NodePartitioningManager(com.facebook.presto.sql.planner.NodePartitioningManager) Session(com.facebook.presto.Session) Sets.newConcurrentHashSet(com.google.common.collect.Sets.newConcurrentHashSet) SCALED_WRITER_DISTRIBUTION(com.facebook.presto.sql.planner.SystemPartitioningHandle.SCALED_WRITER_DISTRIBUTION) Iterables.getOnlyElement(com.google.common.collect.Iterables.getOnlyElement) PlanNodeSearcher(com.facebook.presto.sql.planner.optimizations.PlanNodeSearcher) InternalNode(com.facebook.presto.metadata.InternalNode) PlanNode(com.facebook.presto.spi.plan.PlanNode) Collectors.toList(java.util.stream.Collectors.toList) RemoteTask(com.facebook.presto.execution.RemoteTask) FailureDetector(com.facebook.presto.failureDetector.FailureDetector) TableScanNode(com.facebook.presto.spi.plan.TableScanNode) PartitioningHandle(com.facebook.presto.sql.planner.PartitioningHandle) ForQueryExecution(com.facebook.presto.execution.ForQueryExecution) Metadata(com.facebook.presto.metadata.Metadata) NodePartitionMap(com.facebook.presto.sql.planner.NodePartitionMap) ArrayList(java.util.ArrayList) RemoteTask(com.facebook.presto.execution.RemoteTask) TaskStatus(com.facebook.presto.execution.TaskStatus) SqlStageExecution(com.facebook.presto.execution.SqlStageExecution) SqlStageExecution.createSqlStageExecution(com.facebook.presto.execution.SqlStageExecution.createSqlStageExecution) PlanNodeId(com.facebook.presto.spi.plan.PlanNodeId) StageExecutionState(com.facebook.presto.execution.StageExecutionState) Supplier(java.util.function.Supplier) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) Collectors.toList(java.util.stream.Collectors.toList) NodeSelector(com.facebook.presto.execution.scheduler.nodeSelection.NodeSelector) SplitSource(com.facebook.presto.split.SplitSource) NodeTaskMap(com.facebook.presto.execution.NodeTaskMap) Map(java.util.Map) NodePartitionMap(com.facebook.presto.sql.planner.NodePartitionMap) HashMap(java.util.HashMap) ConnectorId(com.facebook.presto.spi.ConnectorId)

Aggregations

Session (com.facebook.presto.Session)3 RemoteTask (com.facebook.presto.execution.RemoteTask)3 RemoteTaskFactory (com.facebook.presto.execution.RemoteTaskFactory)3 SqlStageExecution (com.facebook.presto.execution.SqlStageExecution)3 StageExecutionState (com.facebook.presto.execution.StageExecutionState)3 StageId (com.facebook.presto.execution.StageId)3 OutputBuffers (com.facebook.presto.execution.buffer.OutputBuffers)3 Metadata (com.facebook.presto.metadata.Metadata)3 PlanNode (com.facebook.presto.spi.plan.PlanNode)3 SplitSourceFactory (com.facebook.presto.sql.planner.SplitSourceFactory)3 PlanFragmentId (com.facebook.presto.sql.planner.plan.PlanFragmentId)3 ImmutableList (com.google.common.collect.ImmutableList)3 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)3 ImmutableSet (com.google.common.collect.ImmutableSet)3 Iterables.getOnlyElement (com.google.common.collect.Iterables.getOnlyElement)3 ListenableFuture (com.google.common.util.concurrent.ListenableFuture)3 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 List (java.util.List)3 Map (java.util.Map)3