Openstack中Scheduler脚本启动流程和调度流程分析之三
1 nova-schedule概述看这幅图,nova中包含了非常多的组件,nova-api,nova-compute,nova-schedule等等。我们要研究的是nova-schedule这个组件。nova-schedule组件的功能其实很简单,它从Queue中取出一个虚拟机实例的请求,并决定这个虚拟机实例应该运行在哪个计算结点(computeserver host)上
1 nova-schedule概述
看这幅图,nova中包含了非常多的组件,nova-api,nova-compute,nova-schedule等等。我们要研究的是nova-schedule这个组件。
nova-schedule组件的功能其实很简单,它从Queue中取出一个虚拟机实例的请求,并决定这个虚拟机实例应该运行在哪个计算结点(compute
2 nova-scheduler启动脚本分析
接下来以nova-2011.3这个版本的源代码为例,深入分析一下nova调度的流程。
打开nova-2011.3\bin目录下的nova-scheduler文件,看到主函数如下:
if
service.wait()
nova-scheduler文件是一个python脚本,其作用就是启动nova-scheduler组件。下面我们来分析一下代码的含义。
2.1 utils.default_flagfile()
尝试寻找设置flagfile(默认是nova.conf)的路径,并加载到输入变量args中。
2.2 flags.FLAGS(sys.argv)
把flagfile中的参数放到flag中,不多说明。
2.3 logging.setup()
设置日志。
2.4 utils.monkey_patch()
2.5 server = service.Service.create(binary='nova-scheduler')
查看nova.service.py文件可以看到,create函数的原型如下:
@classmethod
def
可见create函数是Service的类函数。
在create函数中,初始化了将要创建的Service类的对象的一些参数,包括:
1.将host设置为
socket.gethostname(),即当前节点的主机名。
2.将topic设置为
topic
3.将manager的类名设置为
manager
4.将report_interval设置为默认值10秒。report_interval表示节点将状态报告给数据库的时间间隔。
5.将periodic_interval设置为默认值60秒。periodic_interval表示执行周期行任务的周期。
6.调用Service的构造函数。在构造函数中,设置好上述参数,根据manager的名字导入对应的类并创建实例,也就是创建nova.scheduler.manager.SchedulerManager的对象。SchedulerManager是nova.manager.Manager的子类,负责调度器的管理,也就是在nova/scheduler/manager.py文件中设置了默认的调度器。
7.完成Service对象的创建后,返回。
2.6 service.serve(server)
1.service.serve(server)实际上会调用nova.service.Service类自身的start函数来启动服务。所谓启动服务,主要是创建出一个或多个consumer来接收特定Topic的消息队列的消息,并设置好消息监听。
2.调用nova.service.Service类的wait函数,进入等待状态。
2.7 service.wait()
略。
至此nova-scheduler组件就启动了。
3 调度流程
3.1 消息队列
Openstack中使用的消息队列是RabbitMQ,因为篇幅有限,笔者不展开说明消息队列,我们只需要知道,nova中的各个组件都是通过消息队列来通信的,队列可以通过Topic来区分开。
3.2 流程
1.nova-api接到某个请求,例如“run_instance”,nova-api将请求打包后发到Topic为“schedule”的队列。
2.队列接收到消息后,通知消费者(Consumer)。其实就是通过回调函数处理消息,这里的细节比较复杂,回调过程层层传递,我们只需要知道,最终会调用到nova.scheduler.manager.SchedulerManager的_schedule函数。_schedule函数有几个主要的参数:method、context、topic。
3.在nova.scheduler.manager.SchedulerManager的_schedule函数中,SchedulerManager首先尝试调用默认调度器的形如“schedule_*”(将*号替换成参数method)的函数,如果没有找到,则调用调度器的schedule函数,选择一台主机。
4 scheduler类图
nova-2011.3版本的scheduler类图如下(由于类图过大,所以下面是简化版):
可以看出,所有的调度器类都继承自Scheduler类。子调度器类应该实现自己的schedule函数,但并不是必须的。从上述流程部分的分析,我们知道,SchedulerManager首先尝试调用默认调度器的形如“schedule_*”(将*号替换成参数method)的函数,如果没有找到,则调用调度器的schedule函数。
5 调度算法
5.1 ChanceScheduler
ChanceScheduler实现的是随机算法。
5.2 SimpleScheduler
5.2.1 schedule_run_instance、schedule_start_instance
内部都调用了_schedule_instance函数,选择已启动的并且运行实例数目最少的主机。
5.2.2 schedule_create_volume
选择已启动的并且具有最小容量的主机。
5.2.3 schedule_set_network_host
选择已启动的并且具有最少网络负载的主机。
5.3 VsaSchedulerLeastUsedHos t
继承VSA
5.4 VsaSchedulerMostAvailCap acity
继承VSA
5.5 AbstractScheduler
5.5.1 filter_hosts
过滤从ZoneManager返回的主机列表,只实现的简单的过滤,即满足请求所需内存的主机都被返回。
5.5.2 weigh_hosts
对主机列表赋予权值。本类中只是将每个主机的权值都赋1,更复杂的实现应由子类完成。
5.6 BaseScheduler
BaseScheduler是创建跨域实例的调度器的基类。
BaseScheduler覆写了父类AbstractScheduler中的filter_hosts和weigh_hosts。
5.6.1 filter_hosts
略。
5.6.2 weigh_hosts
略。
5.7 MultiScheduler
nova-scheduler默认的scheduler。MultiScheduler内部包含了多个子调度器。所以原理上它可以根据不同的请求调用不同的调度器。但目前不同的请求调用的都是同一个调度器,即ChanceScheduler,这样的情况在未来应该会改变。
6 修改nova-scheduler(简单)
由于默认的scheduler在nova/scheduler/manager.py中定义的,我们可以修改这个文件,将默认调度器指向我们自己编写的调度器。
更多推荐
所有评论(0)