Flink - Scheduler

本文详细解析了Apache Flink中的任务调度流程与资源分配机制,包括Job资源分配过程、ExecutionGraph的作用、如何通过SlotSharingGroup进行资源复用及实例分配等关键步骤。

Job资源分配的过程,

在submitJob中,会生成ExecutionGraph
最终调用到,

executionGraph.scheduleForExecution(scheduler)

接着,ExecutionGraph

public void scheduleForExecution(SlotProvider slotProvider) throws JobException {
// simply take the vertices without inputs.
for (ExecutionJobVertex ejv : this.tasks.values()) {
if (ejv.getJobVertex().isInputVertex()) {
ejv.scheduleAll(slotProvider, allowQueuedScheduling);
}
}

然后,ExecutionJobVertex

public void scheduleAll(SlotProvider slotProvider, boolean queued) throws NoResourceAvailableException {

ExecutionVertex[] vertices = this.taskVertices;

// kick off the tasks
for (ExecutionVertex ev : vertices) {
ev.scheduleForExecution(slotProvider, queued);
}
}
再,ExecutionVertex
public boolean scheduleForExecution(SlotProvider slotProvider, boolean queued) throws NoResourceAvailableException {
return this.currentExecution.scheduleForExecution(slotProvider, queued);
}

最终,Execution

public boolean scheduleForExecution(SlotProvider slotProvider, boolean queued) throws NoResourceAvailableException {

    final SlotSharingGroup sharingGroup = vertex.getJobVertex().getSlotSharingGroup();
    final CoLocationConstraint locationConstraint = vertex.getLocationConstraint();

    if (transitionState(CREATED, SCHEDULED)) {

        ScheduledUnit toSchedule = locationConstraint == null ?
            new ScheduledUnit(this, sharingGroup) :
            new ScheduledUnit(this, sharingGroup, locationConstraint);

        // IMPORTANT: To prevent leaks of cluster resources, we need to make sure that slots are returned
        //     in all cases where the deployment failed. we use many try {} finally {} clauses to assure that
        final Future<SimpleSlot> slotAllocationFuture = slotProvider.allocateSlot(toSchedule, queued); //异步去申请资源

        // IMPORTANT: We have to use the synchronous handle operation (direct executor) here so
        // that we directly deploy the tasks if the slot allocation future is completed. This is
        // necessary for immediate deployment.
        final Future<Void> deploymentFuture = slotAllocationFuture.handle(new BiFunction<SimpleSlot, Throwable, Void>() {
            @Override
            public Void apply(SimpleSlot simpleSlot, Throwable throwable) {
                if (simpleSlot != null) {
                    try {
                        deployToSlot(simpleSlot); //如果申请到,去部署
                    } catch (Throwable t) {
                        try {
                            simpleSlot.releaseSlot();
                        } finally {
                            markFailed(t);
                        }
                    }
                }
                else {
                    markFailed(throwable);
                }
                return null;
            }
        });
        
        return true;
    }

 

调用到,slotProvider.allocateSlot, slotProvider即Scheduler

@Override
public Future<SimpleSlot> allocateSlot(ScheduledUnit task, boolean allowQueued)
        throws NoResourceAvailableException {

    final Object ret = scheduleTask(task, allowQueued);
    if (ret instanceof SimpleSlot) {
        return FlinkCompletableFuture.completed((SimpleSlot) ret); //如果是SimpleSlot,即已经分配成功,表示future结束
    }
    else if (ret instanceof Future) {
        return (Future) ret; //Future说明没有足够资源,申请还在异步中,继续future
    }
    else {
        throw new RuntimeException();
    }
}

 

scheduleTask

   /**
     * Returns either a {@link SimpleSlot}, or a {@link Future}.
     */
    private Object scheduleTask(ScheduledUnit task, boolean queueIfNoResource) throws NoResourceAvailableException {

        final ExecutionVertex vertex = task.getTaskToExecute().getVertex();
        
        final Iterable<TaskManagerLocation> preferredLocations = vertex.getPreferredLocations();
        final boolean forceExternalLocation = vertex.isScheduleLocalOnly() &&
                                    preferredLocations != null && preferredLocations.iterator().hasNext(); //如果preferredLocations不为空,且vertex仅能local schedule
    
        synchronized (globalLock) { //全局锁
            
            SlotSharingGroup sharingUnit = task.getSlotSharingGroup();
            
            if (sharingUnit != null) { //如果有SlotSharingGroup

                // 1)  === If the task has a slot sharing group, schedule with shared slots ===
                
                final SlotSharingGroupAssignment assignment = sharingUnit.getTaskAssignment();
                final CoLocationConstraint constraint = task.getLocationConstraint();
                
                // get a slot from the group, if the group has one for us (and can fulfill the constraint)
                final SimpleSlot slotFromGroup;
                if (constraint == null) {
                    slotFromGroup = assignment.getSlotForTask(vertex); //通过SlotSharingGroupAssignment来分配slot
                }
                else {
                    slotFromGroup = assignment.getSlotForTask(vertex, constraint);
                }

                SimpleSlot newSlot = null;
                SimpleSlot toUse = null;

                // the following needs to make sure any allocated slot is released in case of an error
                try {
                    
                    // check whether the slot from the group is already what we want.
                    // any slot that is local, or where the assignment was unconstrained is good!
                    if (slotFromGroup != null && slotFromGroup.getLocality() != Locality.NON_LOCAL) { //如果找到local slot
                        updateLocalityCounters(slotFromGroup, vertex);
                        return slotFromGroup; //已经找到合适的slot,返回
                    }
                    
                    
                    // the group did not have a local slot for us. see if we can one (or a better one)
                    // our location preference is either determined by the location constraint, or by the
                    // vertex's preferred locations
                    final Iterable<TaskManagerLocation> locations;
                    final boolean localOnly;
                    if (constraint != null && constraint.isAssigned()) { //如果有constraint
                        locations = Collections.singleton(constraint.getLocation());
                        localOnly = true;
                    }
                    else {
                        locations = vertex.getPreferredLocationsBasedOnInputs(); //否则,以输入节点所分配的slot的location信息,作为Preferred
                        localOnly = forceExternalLocation;
                    }
                    // the group did not have a local slot for us. see if we can one (or a better one)
                    newSlot = getNewSlotForSharingGroup(vertex, locations, assignment, constraint, localOnly); //试图为SharingGroup申请一个新的slot

                    
                    if (slotFromGroup == null || !slotFromGroup.isAlive() || newSlot.getLocality() == Locality.LOCAL) {//如果newSlot是local的,那么就是使用newSlot
                        // if there is no slot from the group, or the new slot is local,
                        // then we use the new slot
                        if (slotFromGroup != null) {
                            slotFromGroup.releaseSlot();
                        }
                        toUse = newSlot; //使用新new的slot
                    }
                    else {
                        // both are available and usable. neither is local. in that case, we may
                        // as well use the slot from the sharing group, to minimize the number of
                        // instances that the job occupies
                        newSlot.releaseSlot();
                        toUse = slotFromGroup;
                    }

                    // if this is the first slot for the co-location constraint, we lock
                    // the location, because we are going to use that slot
                    if (constraint != null && !constraint.isAssigned()) {
                        constraint.lockLocation();
                    }
                    
                    updateLocalityCounters(toUse, vertex);
                }
                
                return toUse; //返回申请的slot
            }
            else { //如果不是共享slot,比较简单
                
                // 2) === schedule without hints and sharing ===
                
                SimpleSlot slot = getFreeSlotForTask(vertex, preferredLocations, forceExternalLocation); //直接申请slot
                if (slot != null) {
                    updateLocalityCounters(slot, vertex);
                    return slot; //申请到了就返回slot
                }
                else {
                    // no resource available now, so queue the request
                    if (queueIfNoResource) { //如果可以queue
                        CompletableFuture<SimpleSlot> future = new FlinkCompletableFuture<>();
                        this.taskQueue.add(new QueuedTask(task, future)); //把task缓存起来,并把future对象返回,表示异步申请
                        return future;
                    }
                }
            }
        }
    }

 

如果有SlotSharingGroup

首先试图从SlotSharingGroupAssignment中分配slot

slotFromGroup = assignment.getSlotForTask(vertex), 参考,Flink – SlotSharingGroup

如果没有发现local的slot,试图为该vertex创建一个新的slot,

newSlot = getNewSlotForSharingGroup(vertex, locations, assignment, constraint, localOnly); //试图为SharingGroup申请一个新的slot

    protected SimpleSlot getNewSlotForSharingGroup(ExecutionVertex vertex,
                                                    Iterable<TaskManagerLocation> requestedLocations,
                                                    SlotSharingGroupAssignment groupAssignment,
                                                    CoLocationConstraint constraint,
                                                    boolean localOnly)
    {
        // we need potentially to loop multiple times, because there may be false positives
        // in the set-with-available-instances
        while (true) {
            Pair<Instance, Locality> instanceLocalityPair = findInstance(requestedLocations, localOnly); //根据locations信息找到local的instance
            
            if (instanceLocalityPair == null) { //如果没有可用的instance,返回null
                // nothing is available
                return null;
            }

            final Instance instanceToUse = instanceLocalityPair.getLeft();
            final Locality locality = instanceLocalityPair.getRight();

            try {
                JobVertexID groupID = vertex.getJobvertexId();
                
                // allocate a shared slot from the instance
                SharedSlot sharedSlot = instanceToUse.allocateSharedSlot(vertex.getJobId(), groupAssignment); //从instance申请一个SharedSlot

                // if the instance has further available slots, re-add it to the set of available resources.
                if (instanceToUse.hasResourcesAvailable()) { //如果这个instance还有多余的资源,再加入instancesWithAvailableResources,下次还能继续用来分配
                    this.instancesWithAvailableResources.put(instanceToUse.getTaskManagerID(), instanceToUse);
                }

                if (sharedSlot != null) {
                    // add the shared slot to the assignment group and allocate a sub-slot
                    SimpleSlot slot = constraint == null ?
                            groupAssignment.addSharedSlotAndAllocateSubSlot(sharedSlot, locality, groupID) : //把分配的SharedSlot加到SlotSharingGroup的SlotSharingGroupAssignment中,并返回SharedSlot所持有的slot
                            groupAssignment.addSharedSlotAndAllocateSubSlot(sharedSlot, locality, constraint);

                    if (slot != null) {
                        return slot;
                    }
                    else {
                        // could not add and allocate the sub-slot, so release shared slot
                        sharedSlot.releaseSlot();
                    }
                }
            }
            catch (InstanceDiedException e) {
                // the instance died it has not yet been propagated to this scheduler
                // remove the instance from the set of available instances
                removeInstance(instanceToUse);
            }

            // if we failed to get a slot, fall through the loop
        }
    }

findInstance

    private Pair<Instance, Locality> findInstance(Iterable<TaskManagerLocation> requestedLocations, boolean localOnly) {
        
        // drain the queue of newly available instances
        while (this.newlyAvailableInstances.size() > 0) { //BlockingQueue<Instance> newlyAvailableInstances
            Instance queuedInstance = this.newlyAvailableInstances.poll();
            if (queuedInstance != null) {
                this.instancesWithAvailableResources.put(queuedInstance.getTaskManagerID(), queuedInstance); // Map<ResourceID, Instance> instancesWithAvailableResources
            }
        }
        
        // if nothing is available at all, return null
        if (this.instancesWithAvailableResources.isEmpty()) {
            return null;
        }

        Iterator<TaskManagerLocation> locations = requestedLocations == null ? null : requestedLocations.iterator();

        if (locations != null && locations.hasNext()) { //如果有prefered locations,优先找相对应的Instance
            // we have a locality preference

            while (locations.hasNext()) {
                TaskManagerLocation location = locations.next();
                if (location != null) {
                    Instance instance = instancesWithAvailableResources.remove(location.getResourceID()); //找到对应于perfer location的Instance
                    if (instance != null) {
                        return new ImmutablePair<Instance, Locality>(instance, Locality.LOCAL);
                    }
                }
            }
            
            // no local instance available
            if (localOnly) { //如果localOnly,而前面又没有找到local的,所以只能返回null
                return null;
            }
            else {
                // take the first instance from the instances with resources
                Iterator<Instance> instances = instancesWithAvailableResources.values().iterator();
                Instance instanceToUse = instances.next();
                instances.remove();

                return new ImmutablePair<>(instanceToUse, Locality.NON_LOCAL); //由于前面没有找到local的,所以返回第一个instance,locality为non_local
            }
        }
        else {
            // no location preference, so use some instance
            Iterator<Instance> instances = instancesWithAvailableResources.values().iterator();
            Instance instanceToUse = instances.next();
            instances.remove();

            return new ImmutablePair<>(instanceToUse, Locality.UNCONSTRAINED); //没有约束,也是取第一个instance,locality为UNCONSTRAINED
        }
    }

Instance.allocateSharedSlot

    public SharedSlot allocateSharedSlot(JobID jobID, SlotSharingGroupAssignment sharingGroupAssignment)
            throws InstanceDiedException
    {
        synchronized (instanceLock) {
            if (isDead) {
                throw new InstanceDiedException(this);
            }

            Integer nextSlot = availableSlots.poll(); //Queue<Integer> availableSlots;
            if (nextSlot == null) {
                return null;
            }
            else {
                SharedSlot slot = new SharedSlot(
                        jobID, this, location, nextSlot, taskManagerGateway, sharingGroupAssignment);
                allocatedSlots.add(slot); //Set<Slot> allocatedSlots
                return slot;
            }
        }
    }

如果新分配的slot是local的,就用newSlot;如果不是并且当前SlotSharingGroup中是有non-local的slot,就用现成的slot,没必要使用新的slot,这时需要把newSlot释放掉

如果没有SlotSharingGroup

简单的调用

SimpleSlot slot = getFreeSlotForTask(vertex, preferredLocations, forceExternalLocation);

     protected SimpleSlot getFreeSlotForTask(ExecutionVertex vertex,
                                            Iterable<TaskManagerLocation> requestedLocations,
                                            boolean localOnly) {
        // we need potentially to loop multiple times, because there may be false positives
        // in the set-with-available-instances
        while (true) {
            Pair<Instance, Locality> instanceLocalityPair = findInstance(requestedLocations, localOnly); //找到一个合适的instance

            if (instanceLocalityPair == null){
                return null;
            }

            Instance instanceToUse = instanceLocalityPair.getLeft();
            Locality locality = instanceLocalityPair.getRight();

            try {
                SimpleSlot slot = instanceToUse.allocateSimpleSlot(vertex.getJobId()); //分配一个simpleSlot
                
                // if the instance has further available slots, re-add it to the set of available resources.
                if (instanceToUse.hasResourcesAvailable()) {
                    this.instancesWithAvailableResources.put(instanceToUse.getTaskManagerID(), instanceToUse);
                }
                
                if (slot != null) {
                    slot.setLocality(locality);
                    return slot;
                }
            }
            catch (InstanceDiedException e) {
                // the instance died it has not yet been propagated to this scheduler
                // remove the instance from the set of available instances
                removeInstance(instanceToUse);
            }
            
            // if we failed to get a slot, fall through the loop
        }
    }

逻辑和分配SharedSlot基本相同,只是会调用,

    public SimpleSlot allocateSimpleSlot(JobID jobID) throws InstanceDiedException {
        if (jobID == null) {
            throw new IllegalArgumentException();
        }

        synchronized (instanceLock) {
            if (isDead) {
                throw new InstanceDiedException(this);
            }

            Integer nextSlot = availableSlots.poll();
            if (nextSlot == null) {
                return null;
            }
            else {
                SimpleSlot slot = new SimpleSlot(jobID, this, location, nextSlot, taskManagerGateway);
                allocatedSlots.add(slot);
                return slot;
            }
        }
    }

 

Instance

Scheduler中的Instance怎么来的?

Scheduler实现InstanceListener接口的

newInstanceAvailable
    @Override
    public void newInstanceAvailable(Instance instance) {
        
        // synchronize globally for instance changes
        synchronized (this.globalLock) {
            
            // check we do not already use this instance
            if (!this.allInstances.add(instance)) { //看看是否已经有了这个instance
                throw new IllegalArgumentException("The instance is already contained.");
            }
            
            try {
                // make sure we get notifications about slots becoming available
                instance.setSlotAvailabilityListener(this); //加上SlotAvailabilityListener,当slot ready的时候,可以被通知
                
                // store the instance in the by-host-lookup
                String instanceHostName = instance.getTaskManagerLocation().getHostname(); 
                Set<Instance> instanceSet = allInstancesByHost.get(instanceHostName); // HashMap<String, Set<Instance>> allInstancesByHost
                if (instanceSet == null) {
                    instanceSet = new HashSet<Instance>();
                    allInstancesByHost.put(instanceHostName, instanceSet);
                }
                instanceSet.add(instance);

                // add it to the available resources and let potential waiters know
                this.instancesWithAvailableResources.put(instance.getTaskManagerID(), instance); // Map<ResourceID, Instance> instancesWithAvailableResources

                // add all slots as available
                for (int i = 0; i < instance.getNumberOfAvailableSlots(); i++) { //多次触发newSlotAvailable
                    newSlotAvailable(instance);
                }
            }
            catch (Throwable t) {
                LOG.error("Scheduler could not add new instance " + instance, t);
                removeInstance(instance);
            }
        }
    }

 

newInstanceAvailable,何时被调用,

 

JobManager

      case msg @ RegisterTaskManager(
          resourceId,
          connectionInfo,
          hardwareInformation,
          numberOfSlots) =>
          
          
          val instanceID = instanceManager.registerTaskManager(
            taskManagerGateway,
            connectionInfo,
            hardwareInformation,
            numberOfSlots)

 

InstanceManager

    public InstanceID registerTaskManager(
            TaskManagerGateway taskManagerGateway,
            TaskManagerLocation taskManagerLocation,
            HardwareDescription resources,
            int numberOfSlots) {
        
        synchronized (this.lock) {

            InstanceID instanceID = new InstanceID();

            Instance host = new Instance(
                taskManagerGateway,
                taskManagerLocation,
                instanceID,
                resources,
                numberOfSlots);

            // notify all listeners (for example the scheduler)
            notifyNewInstance(host);

            return instanceID;
        }
    }

 

    private void notifyNewInstance(Instance instance) {
        synchronized (this.instanceListeners) {
            for (InstanceListener listener : this.instanceListeners) {
                try {
                    listener.newInstanceAvailable(instance);
                }
                catch (Throwable t) {
                    LOG.error("Notification of new instance availability failed.", t);
                }
            }
        }
    }

 

Scheduler还是实现SlotAvailabilityListener

会调用newSlotAvailable

逻辑只是check是否有待分配的task,当有新的slot ready的时候,把queuedTask的future complete掉

@Override
    public void newSlotAvailable(final Instance instance) {
        
        // WARNING: The asynchrony here is necessary, because  we cannot guarantee the order
        // of lock acquisition (global scheduler, instance) and otherwise lead to potential deadlocks:
        // 
        // -> The scheduler needs to grab them (1) global scheduler lock
        //                                     (2) slot/instance lock
        // -> The slot releasing grabs (1) slot/instance (for releasing) and
        //                             (2) scheduler (to check whether to take a new task item
        // 
        // that leads with a high probability to deadlocks, when scheduling fast

        this.newlyAvailableInstances.add(instance);

        Futures.future(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                handleNewSlot();
                return null;
            }
        }, executionContext);
    }
    
    private void handleNewSlot() {
        
        synchronized (globalLock) {
            Instance instance = this.newlyAvailableInstances.poll();
            if (instance == null || !instance.hasResourcesAvailable()) {
                // someone else took it
                return;
            }
            
            QueuedTask queued = taskQueue.peek(); //如果有待分配的task
            
            // the slot was properly released, we can allocate a new one from that instance
            
            if (queued != null) {
                ScheduledUnit task = queued.getTask();
                ExecutionVertex vertex = task.getTaskToExecute().getVertex();
                
                try {
                    SimpleSlot newSlot = instance.allocateSimpleSlot(vertex.getJobId()); //从instance分配一个simpleSlot
                    if (newSlot != null) {
                        
                        // success, remove from the task queue and notify the future
                        taskQueue.poll();
                        if (queued.getFuture() != null) {
                            try {
                                queued.getFuture().complete(newSlot); //complete该task的future,有slot了,你不用继续等了
                            }
                            catch (Throwable t) {
                                LOG.error("Error calling allocation future for task " + vertex.getSimpleName(), t);
                                task.getTaskToExecute().fail(t);
                            }
                        }
                    }
                }
                catch (InstanceDiedException e) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Instance " + instance + " was marked dead asynchronously.");
                    }
                    
                    removeInstance(instance);
                }
            }
            else { //如果没有排队的task,直接把instance放到instancesWithAvailableResources就好
                this.instancesWithAvailableResources.put(instance.getTaskManagerID(), instance);
            }
        }
    }

 

newSlotAvailable除了当new instance注册时被调用外,还会在Instance.returnAllocatedSlot,即有人释放AllocatedSlot时,会被调用

D:\software\develop\java\jdk-1.8\jdk-1.8\bin\java.exe "-javaagent:D:\software\develop\ideal\IntelliJ IDEA 2022.1.3\lib\idea_rt.jar=61865:D:\software\develop\ideal\IntelliJ IDEA 2022.1.3\bin" -Dfile.encoding=UTF-8 -classpath D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\charsets.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\deploy.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\ext\access-bridge-64.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\ext\cldrdata.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\ext\dnsns.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\ext\jaccess.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\ext\jfxrt.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\ext\localedata.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\ext\nashorn.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\ext\sunec.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\ext\sunjce_provider.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\ext\sunmscapi.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\ext\sunpkcs11.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\ext\zipfs.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\javaws.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\jce.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\jfr.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\jfxswt.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\jsse.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\management-agent.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\plugin.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\resources.jar;D:\software\develop\java\jdk-1.8\jdk-1.8\jre\lib\rt.jar;D:\workspace\UserBehaviorAnalysis\HotItemsAnalysis\target\classes;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-table-planner-blink_2.12\1.10.1\flink-table-planner-blink_2.12-1.10.1.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-table-common\1.10.1\flink-table-common-1.10.1.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-table-api-java\1.10.1\flink-table-api-java-1.10.1.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-table-api-scala_2.12\1.10.1\flink-table-api-scala_2.12-1.10.1.jar;D:\software\develop\Apache\maven-repository\org\scala-lang\scala-compiler\2.12.7\scala-compiler-2.12.7.jar;D:\software\develop\Apache\maven-repository\org\scala-lang\modules\scala-xml_2.12\1.0.6\scala-xml_2.12-1.0.6.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-table-api-java-bridge_2.12\1.10.1\flink-table-api-java-bridge_2.12-1.10.1.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-table-api-scala-bridge_2.12\1.10.1\flink-table-api-scala-bridge_2.12-1.10.1.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-scala_2.12\1.10.1\flink-scala_2.12-1.10.1.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-streaming-scala_2.12\1.10.1\flink-streaming-scala_2.12-1.10.1.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-table-runtime-blink_2.12\1.10.1\flink-table-runtime-blink_2.12-1.10.1.jar;D:\software\develop\Apache\maven-repository\org\codehaus\janino\janino\3.0.9\janino-3.0.9.jar;D:\software\develop\Apache\maven-repository\org\codehaus\janino\commons-compiler\3.0.9\commons-compiler-3.0.9.jar;D:\software\develop\Apache\maven-repository\org\apache\calcite\avatica\avatica-core\1.15.0\avatica-core-1.15.0.jar;D:\software\develop\Apache\maven-repository\org\reflections\reflections\0.9.10\reflections-0.9.10.jar;D:\software\develop\Apache\maven-repository\org\javassist\javassist\3.19.0-GA\javassist-3.19.0-GA.jar;D:\software\develop\Apache\maven-repository\org\slf4j\slf4j-api\1.7.15\slf4j-api-1.7.15.jar;D:\software\develop\Apache\maven-repository\com\google\code\findbugs\jsr305\1.3.9\jsr305-1.3.9.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\force-shading\1.10.1\force-shading-1.10.1.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-java\1.10.1\flink-java-1.10.1.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-core\1.10.1\flink-core-1.10.1.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-annotations\1.10.1\flink-annotations-1.10.1.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-metrics-core\1.10.1\flink-metrics-core-1.10.1.jar;D:\software\develop\Apache\maven-repository\com\esotericsoftware\kryo\kryo\2.24.0\kryo-2.24.0.jar;D:\software\develop\Apache\maven-repository\com\esotericsoftware\minlog\minlog\1.2\minlog-1.2.jar;D:\software\develop\Apache\maven-repository\org\objenesis\objenesis\2.1\objenesis-2.1.jar;D:\software\develop\Apache\maven-repository\commons-collections\commons-collections\3.2.2\commons-collections-3.2.2.jar;D:\software\develop\Apache\maven-repository\org\apache\commons\commons-compress\1.18\commons-compress-1.18.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-shaded-asm-7\7.1-9.0\flink-shaded-asm-7-7.1-9.0.jar;D:\software\develop\Apache\maven-repository\org\apache\commons\commons-lang3\3.3.2\commons-lang3-3.3.2.jar;D:\software\develop\Apache\maven-repository\org\apache\commons\commons-math3\3.5\commons-math3-3.5.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-streaming-java_2.12\1.10.1\flink-streaming-java_2.12-1.10.1.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-runtime_2.12\1.10.1\flink-runtime_2.12-1.10.1.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-queryable-state-client-java\1.10.1\flink-queryable-state-client-java-1.10.1.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-hadoop-fs\1.10.1\flink-hadoop-fs-1.10.1.jar;D:\software\develop\Apache\maven-repository\commons-io\commons-io\2.4\commons-io-2.4.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-shaded-netty\4.1.39.Final-9.0\flink-shaded-netty-4.1.39.Final-9.0.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-shaded-jackson\2.10.1-9.0\flink-shaded-jackson-2.10.1-9.0.jar;D:\software\develop\Apache\maven-repository\commons-cli\commons-cli\1.3.1\commons-cli-1.3.1.jar;D:\software\develop\Apache\maven-repository\com\typesafe\akka\akka-actor_2.12\2.5.21\akka-actor_2.12-2.5.21.jar;D:\software\develop\Apache\maven-repository\com\typesafe\config\1.3.3\config-1.3.3.jar;D:\software\develop\Apache\maven-repository\org\scala-lang\modules\scala-java8-compat_2.12\0.8.0\scala-java8-compat_2.12-0.8.0.jar;D:\software\develop\Apache\maven-repository\com\typesafe\akka\akka-stream_2.12\2.5.21\akka-stream_2.12-2.5.21.jar;D:\software\develop\Apache\maven-repository\org\reactivestreams\reactive-streams\1.0.2\reactive-streams-1.0.2.jar;D:\software\develop\Apache\maven-repository\com\typesafe\ssl-config-core_2.12\0.3.7\ssl-config-core_2.12-0.3.7.jar;D:\software\develop\Apache\maven-repository\org\scala-lang\modules\scala-parser-combinators_2.12\1.1.1\scala-parser-combinators_2.12-1.1.1.jar;D:\software\develop\Apache\maven-repository\com\typesafe\akka\akka-protobuf_2.12\2.5.21\akka-protobuf_2.12-2.5.21.jar;D:\software\develop\Apache\maven-repository\com\typesafe\akka\akka-slf4j_2.12\2.5.21\akka-slf4j_2.12-2.5.21.jar;D:\software\develop\Apache\maven-repository\org\clapper\grizzled-slf4j_2.12\1.3.2\grizzled-slf4j_2.12-1.3.2.jar;D:\software\develop\Apache\maven-repository\com\github\scopt\scopt_2.12\3.5.0\scopt_2.12-3.5.0.jar;D:\software\develop\Apache\maven-repository\org\xerial\snappy\snappy-java\1.1.4\snappy-java-1.1.4.jar;D:\software\develop\Apache\maven-repository\com\twitter\chill_2.12\0.7.6\chill_2.12-0.7.6.jar;D:\software\develop\Apache\maven-repository\com\twitter\chill-java\0.7.6\chill-java-0.7.6.jar;D:\software\develop\Apache\maven-repository\org\lz4\lz4-java\1.5.0\lz4-java-1.5.0.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-clients_2.12\1.10.1\flink-clients_2.12-1.10.1.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-optimizer_2.12\1.10.1\flink-optimizer_2.12-1.10.1.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-shaded-guava\18.0-9.0\flink-shaded-guava-18.0-9.0.jar;D:\software\develop\Apache\maven-repository\org\apache\kafka\kafka_2.12\2.2.0\kafka_2.12-2.2.0.jar;D:\software\develop\Apache\maven-repository\org\apache\kafka\kafka-clients\2.2.0\kafka-clients-2.2.0.jar;D:\software\develop\Apache\maven-repository\com\github\luben\zstd-jni\1.3.8-1\zstd-jni-1.3.8-1.jar;D:\software\develop\Apache\maven-repository\com\fasterxml\jackson\core\jackson-databind\2.9.8\jackson-databind-2.9.8.jar;D:\software\develop\Apache\maven-repository\com\fasterxml\jackson\core\jackson-annotations\2.9.0\jackson-annotations-2.9.0.jar;D:\software\develop\Apache\maven-repository\com\fasterxml\jackson\core\jackson-core\2.9.8\jackson-core-2.9.8.jar;D:\software\develop\Apache\maven-repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.9.8\jackson-datatype-jdk8-2.9.8.jar;D:\software\develop\Apache\maven-repository\net\sf\jopt-simple\jopt-simple\5.0.4\jopt-simple-5.0.4.jar;D:\software\develop\Apache\maven-repository\com\yammer\metrics\metrics-core\2.2.0\metrics-core-2.2.0.jar;D:\software\develop\Apache\maven-repository\org\scala-lang\scala-library\2.12.8\scala-library-2.12.8.jar;D:\software\develop\Apache\maven-repository\org\scala-lang\scala-reflect\2.12.8\scala-reflect-2.12.8.jar;D:\software\develop\Apache\maven-repository\com\typesafe\scala-logging\scala-logging_2.12\3.9.0\scala-logging_2.12-3.9.0.jar;D:\software\develop\Apache\maven-repository\com\101tec\zkclient\0.11\zkclient-0.11.jar;D:\software\develop\Apache\maven-repository\org\apache\zookeeper\zookeeper\3.4.13\zookeeper-3.4.13.jar;D:\software\develop\Apache\maven-repository\org\apache\yetus\audience-annotations\0.5.0\audience-annotations-0.5.0.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-connector-kafka_2.12\1.10.1\flink-connector-kafka_2.12-1.10.1.jar;D:\software\develop\Apache\maven-repository\org\apache\flink\flink-connector-kafka-base_2.12\1.10.1\flink-connector-kafka-base_2.12-1.10.1.jar com.atguigu.hotitems_analysis.HotItems SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. Exception in thread "main" java.util.concurrent.ExecutionException: org.apache.flink.runtime.client.JobExecutionException: Job execution failed. at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357) at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1908) at org.apache.flink.streaming.api.environment.StreamExecutionEnvironment.execute(StreamExecutionEnvironment.java:1640) at org.apache.flink.streaming.api.environment.LocalStreamEnvironment.execute(LocalStreamEnvironment.java:74) at org.apache.flink.streaming.api.environment.StreamExecutionEnvironment.execute(StreamExecutionEnvironment.java:1620) at com.atguigu.hotitems_analysis.HotItems.main(HotItems.java:89) Caused by: org.apache.flink.runtime.client.JobExecutionException: Job execution failed. at org.apache.flink.runtime.jobmaster.JobResult.toJobExecutionResult(JobResult.java:147) at org.apache.flink.client.program.PerJobMiniClusterFactory$PerJobMiniClusterJobClient.lambda$getJobExecutionResult$2(PerJobMiniClusterFactory.java:175) at java.util.concurrent.CompletableFuture.uniApply(CompletableFuture.java:616) at java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:591) at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:488) at java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:1975) at org.apache.flink.runtime.concurrent.FutureUtils$1.onComplete(FutureUtils.java:874) at akka.dispatch.OnComplete.internal(Future.scala:264) at akka.dispatch.OnComplete.internal(Future.scala:261) at akka.dispatch.japi$CallbackBridge.apply(Future.scala:191) at akka.dispatch.japi$CallbackBridge.apply(Future.scala:188) at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:64) at org.apache.flink.runtime.concurrent.Executors$DirectExecutionContext.execute(Executors.java:74) at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:72) at scala.concurrent.impl.Promise$DefaultPromise.$anonfun$tryComplete$1(Promise.scala:288) at scala.concurrent.impl.Promise$DefaultPromise.$anonfun$tryComplete$1$adapted(Promise.scala:288) at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:288) at akka.pattern.PromiseActorRef.$bang(AskSupport.scala:573) at akka.pattern.PipeToSupport$PipeableFuture$$anonfun$pipeTo$1.applyOrElse(PipeToSupport.scala:22) at akka.pattern.PipeToSupport$PipeableFuture$$anonfun$pipeTo$1.applyOrElse(PipeToSupport.scala:21) at scala.concurrent.Future.$anonfun$andThen$1(Future.scala:536) at scala.concurrent.impl.Promise.liftedTree1$1(Promise.scala:33) at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:33) at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:64) at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55) at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run$1(BatchingExecutor.scala:91) at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23) at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:85) at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:91) at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40) at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(ForkJoinExecutorConfigurator.scala:44) at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) Caused by: org.apache.flink.runtime.JobException: Recovery is suppressed by NoRestartBackoffTimeStrategy at org.apache.flink.runtime.executiongraph.failover.flip1.ExecutionFailureHandler.handleFailure(ExecutionFailureHandler.java:110) at org.apache.flink.runtime.executiongraph.failover.flip1.ExecutionFailureHandler.getFailureHandlingResult(ExecutionFailureHandler.java:76) at org.apache.flink.runtime.scheduler.DefaultScheduler.handleTaskFailure(DefaultScheduler.java:192) at org.apache.flink.runtime.scheduler.DefaultScheduler.maybeHandleTaskFailure(DefaultScheduler.java:186) at org.apache.flink.runtime.scheduler.DefaultScheduler.updateTaskExecutionStateInternal(DefaultScheduler.java:180) at org.apache.flink.runtime.scheduler.SchedulerBase.updateTaskExecutionState(SchedulerBase.java:496) at org.apache.flink.runtime.jobmaster.JobMaster.updateTaskExecutionState(JobMaster.java:380) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.flink.runtime.rpc.akka.AkkaRpcActor.handleRpcInvocation(AkkaRpcActor.java:284) at org.apache.flink.runtime.rpc.akka.AkkaRpcActor.handleRpcMessage(AkkaRpcActor.java:199) at org.apache.flink.runtime.rpc.akka.FencedAkkaRpcActor.handleRpcMessage(FencedAkkaRpcActor.java:74) at org.apache.flink.runtime.rpc.akka.AkkaRpcActor.handleMessage(AkkaRpcActor.java:152) at akka.japi.pf.UnitCaseStatement.apply(CaseStatements.scala:26) at akka.japi.pf.UnitCaseStatement.apply(CaseStatements.scala:21) at scala.PartialFunction.applyOrElse(PartialFunction.scala:127) at scala.PartialFunction.applyOrElse$(PartialFunction.scala:126) at akka.japi.pf.UnitCaseStatement.applyOrElse(CaseStatements.scala:21) at scala.PartialFunction$OrElse.applyOrElse(PartialFunction.scala:175) at scala.PartialFunction$OrElse.applyOrElse(PartialFunction.scala:176) at scala.PartialFunction$OrElse.applyOrElse(PartialFunction.scala:176) at akka.actor.Actor.aroundReceive(Actor.scala:517) at akka.actor.Actor.aroundReceive$(Actor.scala:515) at akka.actor.AbstractActor.aroundReceive(AbstractActor.scala:225) at akka.actor.ActorCell.receiveMessage(ActorCell.scala:592) at akka.actor.ActorCell.invoke(ActorCell.scala:561) at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:258) at akka.dispatch.Mailbox.run(Mailbox.scala:225) at akka.dispatch.Mailbox.exec(Mailbox.scala:235) ... 4 more Caused by: java.lang.IllegalStateException: No entry found for connection 3 at org.apache.kafka.clients.ClusterConnectionStates.nodeState(ClusterConnectionStates.java:339) at org.apache.kafka.clients.ClusterConnectionStates.disconnected(ClusterConnectionStates.java:143) at org.apache.kafka.clients.NetworkClient.initiateConnect(NetworkClient.java:926) at org.apache.kafka.clients.NetworkClient.ready(NetworkClient.java:287) at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.trySend(ConsumerNetworkClient.java:474) at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:255) at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:236) at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:215) at org.apache.kafka.clients.consumer.internals.Fetcher.getTopicMetadata(Fetcher.java:292) at org.apache.kafka.clients.consumer.KafkaConsumer.partitionsFor(KafkaConsumer.java:1803) at org.apache.kafka.clients.consumer.KafkaConsumer.partitionsFor(KafkaConsumer.java:1771) at org.apache.flink.streaming.connectors.kafka.internal.KafkaPartitionDiscoverer.getAllPartitionsForTopics(KafkaPartitionDiscoverer.java:77) at org.apache.flink.streaming.connectors.kafka.internals.AbstractPartitionDiscoverer.discoverPartitions(AbstractPartitionDiscoverer.java:131) at org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumerBase.open(FlinkKafkaConsumerBase.java:511) at org.apache.flink.api.common.functions.util.FunctionUtils.openFunction(FunctionUtils.java:36) at org.apache.flink.streaming.api.operators.AbstractUdfStreamOperator.open(AbstractUdfStreamOperator.java:102) at org.apache.flink.streaming.runtime.tasks.StreamTask.initializeStateAndOpen(StreamTask.java:990) at org.apache.flink.streaming.runtime.tasks.StreamTask.lambda$beforeInvoke$0(StreamTask.java:453) at org.apache.flink.streaming.runtime.tasks.StreamTaskActionExecutor$SynchronizedStreamTaskActionExecutor.runThrowing(StreamTaskActionExecutor.java:94) at org.apache.flink.streaming.runtime.tasks.StreamTask.beforeInvoke(StreamTask.java:448) at org.apache.flink.streaming.runtime.tasks.StreamTask.invoke(StreamTask.java:460) at org.apache.flink.runtime.taskmanager.Task.doRun(Task.java:708) at org.apache.flink.runtime.taskmanager.Task.run(Task.java:533) at java.lang.Thread.run(Thread.java:750) Process finished with exit code 1
最新发布
06-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值