zoukankan      html  css  js  c++  java
  • cello相关流程

    scheduler添加任务流程

    用户调用Submit函数(如果是自动伸缩的模式,Submit函数将不会被调用,在AutoScaleFrameWork的Init函数中会自己创建一个Task,插入m_wait_queue中而不用TaskProcessor调度),该函数将构建Task结构,并同时插入Task buffer(仅仅是为RPC而写的接口缓冲而使用的),和Task Pool,由TaskProcessor从TaskBuffer中线程取出,调用PlugTask(注意,如果是AutoScaleFramework,则PlugTask会调用SetInfo,设置Task的相关资源,因为AddExecutor时候只提供了Framework ID,没有其他的信息)加入到相应VC中的wait队列。最后由SchedulerProcessor线程周期性从VCPool取出取出Task进行调用AssignTask,该函数匹配运行的的节点资源,然后调用cellet的StartTask函数接口。

    若操作成功,TaskProcessor然后带调用TaskAssigned改变Task的状态为运行,但是此时Task还没有被加入framework的运行队列。这个是为什么? 加入运行队列是在cellet调用TaskStart函数之后加入的。(是不是加一个处理状态比较好?)

    若失败,则调用AddTask把Task交回去等待下一次调度。

    cello container启动过程

    在Container::Execute()函数中,在执行lxc_start之前fork了一个子进程,在子进程中首先调用了CloseInheritedFD,重定向了log,然后调用了lxc_start执行命令,最后调用exit退出。

    父进程就先睡了1秒钟,然后调用ContainerStarted函数,这个函数调用了SetResourceLimit限制了Container的资源。限制资源是通过lxc_cgroup_set设置memory.limit_in_bytes以及cpu.shares。

    cello container 启动失败上报过程

    如果在初始化Container(Init函数)过程中出错,会调用ContainerFinished函数,该函数将Container的状态改为FINISHED,然后向EXECUTOR_STATE_KEY队列发送了一个消息。该消息会由线程ExecutorStatusReceiver接收,该线程根据消息类型生成ContainerState,调用StateHandler处理这个消息,调用MasterService的TaskFinished给master发送消息,同时设置Executor的状态。

    cello worker节点任务执行过程

    Master调用接口WorkerService的函数StartTask,初始化一个Exectuor插入池中,然后等待StartExecutorSender线程调度。该线程会调用StartExecutor从pool中找到一个等待中的Executor,然后调用Executor的Start函数,该函数会形成一消息发往Executor运行消息队列,并将Executor状态改为执行中。线程StartExecutorReceiver线程会接受到它发的相应消息并处理,具体处理过程为:初始化一个Container结构,调用Container的Init函数初始化一些目录,再调用Executor()函数启动containter(参看cello启动Container过程),并插入Executor池中。

    scheduler接收到Cellet回报状态流程

    cellet调用TaskStarted,该函数会形成一个StartEvent,并由EventDispather调用Dispatch下发到相应事件队列里面去,这些事件的处理线程是在相应Handler::Handle中取出事件并调用其Handle函数,这些Handle线程由Handler::Start启动,这个Start函数是由scheduler.cpp的main函数注册之后调用。这样应该可以做到动态的添加事件类型。

    scheduler 的事件处理

    StartEvent,如果是成功启动,就找到这个Task,然后调用FrameworkPool::AddTask,把这个Task加入到运行队列里面去

                      如果失败,就在Pool里面把这个Task删除掉

    FinishEvent,找到相应Task,调用FrameworkPool::RemoveTask,然后在Pool里面把这个任务杀掉

    ExecutorState 在collecotor中被处理的流程

    状态信息通过心跳中MachineInfo中的子结构list<ExecutorState>发送到collector 服务端,然后被加入到Monitor的机器队列(m_queue中) ,这个队列被Monitor启动的线程周期性取出并解析然后转发到相应的Framework中的ExecutorState队列中,(Monitor里面维护着Framework pool),每一个Framework被启动的时候,会伴随启动一个线程,并安装一个框架整体触发器,这个线程会取出自身的ExecutorState队列中的状态,将其加入到相应ExecutorInMachine结构中,并察看整体的trigger是否满足并触发。每个ExecutorState启动时候,也伴随一个触发器以及一个监控触发器是否触发的线程。

    cello添加framework的流程:

    用户调用SchedulerService::AddFramewrok,该函数由StandardPool和AutoScalePool分别实现。

    在AutoScalePool中,AddFramework中,会创建一个AutoScaleFramework结构,并调用其Init函数,最后将这个结构插入自身的FrameworkPool中。这个Init函数初始化了一个Task,插TaskPool和m_wait_queue中,等待SchedulerProceesor的调度,被形成一个Event,被调用Handle函数。

    cello中自动删除Executor的流程:

    当Idle触发器触发之后,Collect会调用SchedulerService::DeleteExecutor RPC调用,这个会调用SchedulerService::RemoveTask,该函数会形成一个Remove Event,然后由EventDispatcher分发,并由相应的事件处理线程进行处理,调用其Handle函数,这个函数绑定FrameworkPool::KillTask,再调用Framework::KillTask,最终会产生一个KillActionEvent,再由EventDispatcher进行分发,最后处理,KillActionEvent会调用cellet RPC接口 KillExecutor,详细流程见下。

    cellet 杀掉Executor的流程:

    CelletService::KillExecutor,会调用ExecutorPool::DeleteExecutor,该函数会绑定并调用Executor::Kill。Kill函数会产生形成一个(KillEvent)消息并发送到EXECUTOR_CONTROL消息队列里面去,将Executor的相应状态改为EXECUTOR_KILLED。这个队列里面的消息会被ExecutorControlReceiver线程调度,形成一个KillEvent,调用ContainerMgr::Instance()->DeleteByTaskId(GetId())删除Executor。

  • 相关阅读:
    Redis5设计与源码分析 (第17章 HyperLogLog相关命令的实现)
    Redis5设计与源码分析 (第16章 GEO相关命令)
    ES5和ES6函数的this指向
    vue响应式原理 (响应式并不等于数据双向绑定,千万不要混淆)
    vue中data为什么是函数而不是对象
    vue-enum 前端常量 枚举工具
    Vue3 写业务逻辑不适合用TS(TypeScript)
    vue-property-decorator vue3 ts 用的装饰器
    github git clone下载加速 && npm install 下载加速
    vue3 如果用ts,导出时候要用 defineComponent,这俩是配对的,为了类型的审查正确
  • 原文地址:https://www.cnblogs.com/zhangzhang/p/2923211.html
Copyright © 2011-2022 走看看