Nova Scheduler 调度过程简述

      《Nova创建虚拟机实例过程简述》文章中,讲述了创建虚拟机实例的一个整体过程,现在,我们要开始着重分析和研究compute-api将请求发送到Scheduler后,Scheduler是如何实现初始调度工作的。

关于Scheduler的作用资料很多,我下面就引用下大神的一段话(

“Nova-Scheduler主要完成虚拟机实例的调度分配任务,创建虚拟机时,虚拟机该调度到哪台物理机上,迁移时若没有指定主机,也需要经过scheduler。资源调度是云平台中的一个很关键问题,如何做到资源的有效分配,如何满足不同情况的分配方式,这些都需要nova-scheduler来掌控,并且能够很方便的扩展更多的调度方法,可能我需要虚拟机调度到空闲的机器,可能还需要将某类型的虚拟机调度到固定的机架等等”


下面让我们来看一看具体的调度过程。

(一)Scheduler启动相关分析

         (1)compute-api通过一层层调用,最后调用/nova/compute/manager.py的run_instance(),如下图:

	#启动虚拟机
	def run_instance(self, context, request_spec, admin_password,
            injected_files, requested_networks, is_first_time,
            filter_properties, legacy_bdm_in_spec=True):
        """Tries to call schedule_run_instance on the driver.
	
        Sets instance vm_state to ERROR on exceptions
        """
        instance_uuids = request_spec['instance_uuids']
		"""Compute-related Utilities and helpers."""
		#compute_utils = utils
		#EventReoprt()是一个类
        with compute_utils.EventReporter(context, conductor_api.LocalAPI(),
                                         'schedule', *instance_uuids):
            try:
				 
				#调用driver(filter_scheduler.py)中的schedule_run_instance()
                return self.driver.schedule_run_instance(context,
                        request_spec, admin_password, injected_files,
                        requested_networks, is_first_time, filter_properties,
                        legacy_bdm_in_spec)

最后调用 self.driver.schedule_run_instance(context,***)

我们再来看看,这个driver是什么东西

scheduler_driver_opt = cfg.StrOpt('scheduler_driver',
        default='nova.scheduler.filter_scheduler.FilterScheduler',
        help='Default driver to use for the scheduler')
这里配置文件中,Scheduler_driver的默认值 default = nova.scheduler.filter_scheduler.FilterScheduler

注意,在早些版本的时候,这个默认值都是MultiScheduler,现在nova-volumn用一个新的项目cinder代替了,所以,也就不采用原来的那个方案了。直接driver= FilterScheduler

  

     (2)通过self.driver.schedule_run_instance(context,***)调用,我们转到了/nova/scheduler/filter_scheduler.py文件,看到class FilterScheduler类。

 def schedule_run_instance(self, context, request_spec,
                              admin_password, injected_files,
                              requested_networks, is_first_time,
                              filter_properties, legacy_bdm_in_spec):
        """This method is called from nova.compute.api to provision
        an instance.  We first create a build plan (a list of WeightedHosts)
        and then provision.

        Returns a list of the instances created.
        """
        payload = dict(request_spec=request_spec)
        self.notifier.info(context, 'scheduler.run_instance.start', payload)

        instance_uuids = request_spec.get('instance_uuids')
        LOG.info(_("Attempting to build %(num_instances)d instance(s) "
                    "uuids: %(instance_uuids)s"),
                  {'num_instances': len(instance_uuids),
                   'instance_uuids': instance_uuids})
        LOG.debug(_("Request Spec: %s") % request_spec)


schedule_run_instance()这个函数里面有一个非常重要的语句是:

#*******************开始调用_schedule方法,来实现调度******************************#
		#关键调用
		#通过下面的_schedule()进行调度,返回list_host
        weighed_hosts = self._schedule(context, request_spec,
                                       filter_properties, instance_uuids)
		#**********************************************************************************#

上述通过_scheduler来调度产生最终筛选好的compute node,即weight_hosts(当然,它返回的是一个列表)


(二)让我们看看_scheduler()到底做了什么?
         _scheduler()方法的标准定义如下:
                    ""Returns a list of hosts that meet the required specs,ordered by their fitness.""  ------定义简单明了

FilterScheduler的过程分为两步=Filter+weight,如下图所示



这一个图是官方提供的非常经典的主机过滤过程流程图,照着这个图,我们再去理解代码的含义会相对简单一点。
过程分为1->2->3,最后黄色的host即为_schedule的返回值,下面是对该图过程的具体解释


(1)先解决途中1的hosts是从哪里来的,在_schedule中,我们看到了如下的调用:

hosts = self.host_manager.get_all_host_states(elevated)

再来看上面的函数,我们打开/nova/shceduler/host_manager.py文件,找到对应的get_all_states()方法
 def get_all_host_states(self, context):
        """Returns a list of HostStates that represents all the hosts
        the HostManager knows about.

		Also, each of the consumable resources
        in HostState are pre-populated and adjusted based on data in the db.
        """

        # Get resource usage across the available compute nodes:
		#通过下面的语句,在数据库中得到所有的计算节点信息
		#IMPL.compute_node_get_all(context, no_date_fields)
        compute_nodes = db.compute_node_get_all(context)

(2)在获取到了hosts列表之后,接下来的工作当然是图中的第2步,Filter,函数调用如下:
hosts = self.host_manager.get_filtered_hosts(hosts,
                    filter_properties, index=num)

将filter_proprerties,hosts作为参数传到get_filtered_hosts()函数中去,得到Filter之后的hosts

(3)第一次筛选过后,要开始计算每个host的权值,也就是图中的第三步。
weighed_hosts = self.host_manager.get_weighed_hosts(hosts,
                    filter_properties)

(4)最后返回选择好的主机给compute去执行

在_schedule函数中:
return selected_hosts

在/nova/scheduler/filetr_scheduler中,将weight_hosts再通过另外的函数去执行。
 weighed_hosts = self._schedule(context, request_spec,
                                       filter_properties, instance_uuids)

下面有很多比较重要的参数,比如filter_properties,scheduler_hints,request_spec等等,我会通过另外的博文来说明这几个参数到底指代的是什么东西,这里不做讨论。另外,Scheduler的具体细节也是以后再做介绍
好了,一个简单的Scheduler 调度过程讲述完毕,望大神指教 吐舌头




  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值