zoukankan      html  css  js  c++  java
  • 架构、服务OpenStack源码探秘(一)——NovaSchedulerby小雨

    这几周朋友几篇文章介绍了改架构、服务-的文章. 关联文章的地址

        久许没有更新OpenStack源码探秘系列了。近来换任务颇不顺遂,多许笔者心仪的公司都因为这样或那样的原因而臂交之失,这样下去可能会考虑到互联网公司做些服务器端的任务。晚上回到家情心都不太好,懒得动笔,不过经过了几天伏起,心态也慢慢整调过来了,明天就给大家分享一篇Nova-Scheduler的源码架构分析。

        

                Nova的代码比相Glance说来要杂复多许,团体的架构类似于Twisted的异步回调消息架构,通过AMPQ框架(RabbitMQ)现实了服务间的消息传递制机。关于Nova的团体架构的文章CSDN上有多许,大家可以看做看引伸浏览,不过可能要需握掌些基础知识才能读懂。这里先临时置搁,以后计划好可能会给大家行进些心得的分享。

                选择Nova-Scheduler这个服务作为OpenStack源码探秘系列的扫尾,是因为Nova-Scheduler的架构是比较简略易懂的,万事扫尾难,合适开篇。然后Nova-Scheduler在OpenStack中的用作是却非常重要的,担任虚拟机的度调,决议虚拟机或volume盘磁行运在哪台物理服务器上。Nova-Scheduler看似简略,是因为其现实了非常好的架构,便利我们开辟者根据公司的业务或产品特色,自行增加开辟合适我们的度调算法。

                我们先大体分析Nova-Scheduler的团体构结:

                看一下Nova-Scheduler的服务管理口入,Manage.py(OpenStack有所服务的口入都是以这个名字名命的),看看虚机度调现实了那些功能

    class SchedulerManager(manager.Manager):
        """Chooses a host to run instances on."""
    
        RPC_API_VERSION = '2.6'
    
        def __init__(self, scheduler_driver=None, *args, **kwargs):
            ......
    
        def update_service_capabilities(self, context, service_name,
                                        host, capabilities):
            """Process a capability update from a service node."""
            if not isinstance(capabilities, list):
            ......
    
        def create_volume(self, context, volume_id, snapshot_id,
                          reservations=None, image_id=None):
            #function removed in RPC API 2.3
            pass
    
        def live_migration(self, context, instance, dest,
                           block_migration, disk_over_commit):
            ......
    
        def run_instance(self, context, request_spec, admin_password,
                injected_files, requested_networks, is_first_time,
                filter_properties):
            """Tries to call schedule_run_instance on the driver.
            Sets instance vm_state to ERROR on exceptions
            """
            ......
    
        def prep_resize(self, context, image, request_spec, filter_properties,
                        instance, instance_type, reservations):
            """Tries to call schedule_prep_resize on the driver.
            Sets instance vm_state to ACTIVE on NoHostFound
            Sets vm_state to ERROR on other exceptions
            """
    	......
    
        def show_host_resources(self, context, host):
            """Shows the physical/usage resource given by hosts.
    
            :param context: security context
            :param host: hostname
            :returns:
                example format is below::
    
                    {'resource':D, 'usage':{proj_id1:D, proj_id2:D}}
                    D: {'vcpus': 3, 'memory_mb': 2048, 'local_gb': 2048,
                        'vcpus_used': 12, 'memory_mb_used': 10240,
                        'local_gb_used': 64}
    
            """
            # Getting compute node info and related instances info
            ......
    
        def select_hosts(self, context, request_spec, filter_properties):
            """Returns host(s) best suited for this request_spec and
            filter_properties"""
            ......

                只是对部分代码行进了节选,我们看到SchedulerManger提供的服务包括run_instance(启动虚拟机)、live_migration(虚拟机动态迁移)、prep_resize(虚拟机资源再分配)这几个服务都要需决议虚拟机度调到哪个物理节点。

                决策一个虚机应该度调到某物理节点,要需分两个步骤:过滤(Fliter)和计算权值(Weight):

                1、通过过滤(Fliter),我们过滤掉不符合我们的要求,或镜像要求(比如物理节点不支持64bit,物理节点不支持Vmware EXi等)的主机,留下符合过滤算法的主机集合。

        

                2、第二步行进虚机消耗权值的计算。通过指定的权值计算算法,计算在某物理节点上申请这个虚机所必须的消耗cost,物理节点越不合适这个虚机,消耗cost就越大,权值Weight就越大,度调算法会选择权值最小的主机。比如说在一台低性能主机上创建一台功能杂复的高级虚拟机的代价是高的。配置文件中默认的算法是主机的剩余内存越大,权值越低,就越容易被选上。

        

                OpenStack默认支多种过滤策略,如CoreFilter(CPU数过滤策略)、RamFilter(Ram值选择策略)、AvailabilityZoneFilter(指定集群内主机策略)、JsonFiliter(JSON串指定规则策略)。开辟者也可以现实自己的过滤策略。在nova.scheduler.filters包中的过滤器有以下几种:

        

                下面我们来看一下Filter的UML图:

        

        Filter相关类图

                一提到策略、算法等等的字眼,我们在设计模式中自然就会想到Strategy模式(策略模式)。策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

        

                Filter过滤和cost_weight权值计算确实是应用了这样的场景,统一各个算法的接口,通过HostFilterHandler(Context)类,动态的选择单一算法或算法组合。每个Filter子类都分别现实了host_passes接口,它们使用各自的算法,将传入参数的host_state主机行进过滤,返回boolen,判断这个传入的物理节点是否符合过滤要求。HostFilterHandler类通过继承基类BaseFilterHandler的get_filtered_objects方法,使用ConcreteFilter的算法,并在行运时刻动态动态设置应用哪个或那几个算法。

        

                另外Filter算法在nova-scheduler中是通过oslo.config.cfg模块从nova.conf配置文件中动态读取的,应用了Python的反射制机,在行运时刻决议初始化某些filter算法子类,在不要需重新编译和修改代码的前提下,便捷的替换功能。

    def get_filtered_objects(self, filter_classes, objs,
                filter_properties):
            for filter_cls in filter_classes:
                objs = filter_cls().filter_all(objs, filter_properties)
            return list(objs)

                分析了多许OpenStack的代码,应用设计模式的经典例子确实很多。很晚了,明天先写到这里,后面有时间会分享OpenStack其他模块的代码,欢迎关注、讨论。

    文章结束给大家分享下程序员的一些笑话语录: 一个合格的程序员是不会写出 诸如 “摧毁地球” 这样的程序的,他们会写一个函数叫 “摧毁行星”而把地球当一个参数传进去。

  • 相关阅读:
    Java面向对象编程 -1.3
    Java面向对象编程 -1.2
    Java面向对象编程 -1
    Java基础 -5.3
    Java基础 -5.2
    oracle 新建用户
    js密码的匹配正则
    oracle导入和导出和授权
    oracle存储过程语法
    java.lang.NumberFormatException: For input string: "26.0"
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3026188.html
Copyright © 2011-2022 走看看