Openstack中Scheduler脚本启动流程和调度流程分析之三
2012-09-18 11:51
537 查看
1 nova-schedule概述
nova-schedule组件的功能其实很简单,它从Queue中取出一个虚拟机实例的请求,并决定这个虚拟机实例应该运行在哪个计算结点(compute
server host)上。但是,nova-schedule组件会渐渐变得复杂,因为它需要考虑当前的云基础平台的运行状态,并使用某些复杂的算法来达到资源的有效利用。为了这个目的,nova-schedule实现了可插拔的架构,让我们可以选择已有的算法或写出自己的算法。
2 nova-scheduler启动脚本分析
接下来以nova-2011.3这个版本的源代码为例,深入分析一下nova调度的流程。打开nova-2011.3\bin目录下的nova-scheduler文件,看到主函数如下:
if __name__ == '__main__':
utils.default_flagfile()
flags.FLAGS(sys.argv)
logging.setup()
utils.monkey_patch()
server = service.Service.create(binary='nova-scheduler')
service.serve(server)
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(cls,
host=None,
binary=None,
topic=None,
manager=None,
report_interval=None,
periodic_interval=None)
可见create函数是Service的类函数。
在create函数中,初始化了将要创建的Service类的对象的一些参数,包括:
1.将host设置为
socket.gethostname(),即当前节点的主机名。
2.将topic设置为
topic = binary.rpartition('nova-')[2],即“scheduler”。
3.将manager的类名设置为
manager = FLAGS.get('%s_manager'%
topic, None),即"nova.scheduler.manager.SchedulerManager"。
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 VsaSchedulerLeastUsedHost
继承VSA scheduler,选择具有最少使用能力的主机。5.4 VsaSchedulerMostAvailCapacity
继承VSA scheduler,选择具有某种类型的最多可用容量的主机。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中定义的,我们可以修改这个文件,将默认调度器指向我们自己编写的调度器。相关文章推荐
- 【OpenStack源码分析之六】从虚拟机启动流程看安全认证
- HBase集群启动脚本流程分析
- 【OpenStack源码分析之十】虚机启动流程中Nova Compute与周边组件的交互
- Openwrt启动流程及启动脚本分析
- Openwrt启动流程及启动脚本分析
- Openwrt启动流程及启动脚本分析
- Openwrt启动流程及启动脚本分析
- Openwrt启动流程及启动脚本分析
- Openwrt启动流程及启动脚本分析
- Openwrt启动流程及启动脚本分析
- 【OpenStack源码分析之三】Nova-Compute启动流程分析
- hadoop集群启动脚本分析
- linux启动流程分析
- linux 的 XWindows系统启动脚本分析
- Android APP启动方式、启动流程及启动优化分析
- u-boot移植(一)---u-boot启动流程分析
- bootloader的启动流程分析
- uboot启动流程分析之一
- [转载] linux启动流程分析(2)---内核启动地址的确定
- OpenWrt启动过程分析+添加自启动脚本