Cinder的cinder-scheduler源码解读
程序员文章站
2022-05-11 15:41:59
...
与Nova中的调度服务nova-scheduler类似,Cinder的调度服务cinder-scheduler也用于选择一个合适的节点,不过不同的是nova-scheduler选择的是计算节点来响应用户有关虚拟机生命周期的请求,而cinder-scheduler选择的是cinder-volume节点来处理用户有关Volume周期的请求。
同样,cinder-scheduler选择的方式也可以有很多种,为了便于之后的扩展,Cinder将一个调度器必须实现的接口提取出来成为cinder.scheduler.driver.Scheduler,只要继承类SchedulerDriver并实现其中的接口,就可以实现一个自己的调度器。
# cinder / scheduler / driver.py
class Scheduler(object):
"""The base class that all Scheduler classes should inherit from."""
目前,Cinder中只实现了一个调度器FilterScheduler,但是历史上曾经存在SimpleScheduler(选择剩余空间最多的Host)和ChanceFilter(随机挑选满足条件的Host)两个调度器,但是它们现在已经被利用FilterScheduler的框架重新实现。
# cinder / scheduler / filter_scheduler.py
class FilterScheduler(driver.Scheduler):
"""Scheduler that can be used for filtering and weighing."""
def __init__(self, *args, **kwargs):
super(FilterScheduler, self).__init__(*args, **kwargs)
self.cost_function_cache = None
self.options = scheduler_options.SchedulerOptions()
self.max_attempts = self._max_attempts()
不同的调度器不能共存,需要在/etc/cinder/cinder.conf中通过scheduler_driver选项指定,默认使用的即是FilterScheduler
Default scheduler driver to use (string value)
#scheduler_driver=cinder.scheduler.filter_scheduler.FilterScheduler
FilterScheduler的工作流程基本与Nova的FilterScheduler调度器相同。
FilterScheduler首先使用指定的Filter(过滤器)得到符合条件的cinder-volume节点,比如Volume有足够的存储空间,然后对得到的主机列表计算权重并排序,获得最佳的一个。
完整来说这个过程分为几个阶段:
一 通过cinder.scheduler.rpcapi.SchedulerAPI发出RPC请求
通常Openstack项目中各个服务所在的目录都会有一个rpcapi.py文件,其中定义了所能提供的RPC接口。对于cinder-scheduler服务来说,其他服务将cinder.scheduler.rpcapi模块导入就可以使用其定义的接口远程调用cinder-scheduler提供的服务。cinder-scheduler注册的RPC Server接收到RPC请求后,再由cinder.scheduler.manager.SchedulerManger真正地完成选择cinder-volume节点的操作。
# cinder / scheduler / rpcapi.py
class SchedulerAPI(object):
RPC_API_VERSION = '1.0'
def __init__(self):
super(SchedulerAPI, self).__init__()
target = messaging.Target(topic=CONF.scheduler_topic,
version=self.RPC_API_VERSION)
self.client = rpc.get_client(target, version_cap='1.7')
def create_volume(self, ctxt, topic, volume_id, snapshot_id=None,
image_id=None, request_spec=None,
filter_properties=None):
cctxt = self.client.prepare(version='1.2')
request_spec_p = jsonutils.to_primitive(request_spec)
return cctxt.cast(ctxt, 'create_volume',
topic=topic,
volume_id=volume_id,
snapshot_id=snapshot_id,
image_id=image_id,
request_spec=request_spec_p,
filter_properties=filter_properties)
# cinder / scheduler / manager.py
class SchedulerManager(manager.Manager):
"""Chooses a host to create volumes."""
def create_volume(self, context, topic, volume_id, snapshot_id=None,
image_id=None, request_spec=None,
filter_properties=None):
try:
flow_engine = create_volume.get_flow(context,
db, self.driver,
request_spec,
filter_properties,
volume_id,
snapshot_id,
image_id)
except Exception:
LOG.exception(_("Failed to create scheduler manager volume flow"))
raise exception.CinderException(
_("Failed to create scheduler manager volume flow"))
with flow_utils.DynamicLogListener(flow_engine, logger=LOG):
flow_engine.run()
二 从SchedulerManager到调度器(类SchedulerDiver)
类SchedulerManager用于接收RPC请求,在一些参数验证之后,将请求交由具体的调度器来处理,它在RPC客户端和具体调度器之间起到一个桥梁作用。
类SchedulerManager初始化的时候会根据配置文件/etc/cinder/cinder.conf中选项scheduler_driver的值初始化相应的调度器。
三 Filtering(过滤)与Weighing(权重计算与排序)
Filtering就是使用配置中指定的各种Filters去过滤掉不符合条件的主机,Weighing则是对所有符合条件的主机计算权重(Weight)并排序从而得到最佳的一个。Cinder中已经实现了几种不同的Filter和Weight,所有Filter的实现位于cinder/scheduler/filters目录,所有Weigher的实现位于cinder/scheduler/weights目录。
Filter与Weigher的实现都有特定的要求,比如所有的Filter都必须继承自cinder.openstack.common.scheduler.BaseHostFilter,我们也可以很方便通过继承类BaseHostFilter来创建一个新的Filter,新建的Filter只需实现一个函数host_passes(),返回结果只有两种,满足条件返回True,否则返回False。
我们也可以在配置文件中指定哪些Filter与Weigher:
#scheduler_default_filters=AvailabilityZoneFilter,CapacityFilter,CapabilitiesFilter
# Which weigher class names to use for weighing hosts. (list value)
#scheduler_default_weighers=CapacityWeigher
上一篇: 这么姐弟俩好幽默
下一篇: 走路总是一瘸一拐的真的笑了
推荐阅读
-
Vue源码解读之Component组件注册的实现
-
jQuery选择器源码解读(四):tokenize方法的Expr.preFilter
-
jQuery选择器源码解读(五):tokenize的解析过程
-
Asp.Net Core Authorize你不知道的那些事(源码解读)
-
hadoop2.6源码解读之DFSClient方法调用的RPC流程讲解
-
SpringMVC处理器适配器--源码解读前置知识HandlerMethodArgumentResolver与HandlerMethodReturnV接口的使用
-
源码解读 Golang 的 sync.Map 实现原理
-
Vue源码解读之Component组件注册的实现
-
11.Spark Streaming源码解读之Driver中的ReceiverTracker架构设计以及具体实现彻底研究
-
11.Spark Streaming源码解读之Driver中的ReceiverTracker架构设计以及具体实现彻底研究