zoukankan      html  css  js  c++  java
  • Nova 如何统计 OpenStack 资源

    1、云计算的本质在于将硬件资源软件化,以达到快速按需交付的效果,最基本的计算、存储和网络基础元素并没有因此改变。就计算而言,CPU、RAM 和 DISK等依旧是必不可少的核心资源。

    从源代码和数据库相关表可以得出,Nova 统计计算节点的四类计算资源:

    • CPU: 包括 vcpus(节点物理 cpu 总线程数), vcpus_used(该节点虚拟机的 vcpu 总和)

    • RAM: 包括 memory_mb(该节点总 ram),memory_mb_used(该节点虚拟机的 ram 总和),free_ram_mb(可用 ram) Note: memory_mb = memory_mb_used + free_ram_mb

    • DISK:local_gb(该节点虚拟机的总可用 disk),local_gb_used(该节点虚拟机 disk 总和),free_disk_gb(可用 disk) Note:local_gb = local_gb_used + free_disk_gb*

    • 其它:PCI 设备、CPU 拓扑、NUMA 拓扑和 Hypervisor 等信息

    从代码可以看出,Nova 每分钟统计一次资源,方式如下:

    • CPU

      • vcpus: libvirt 中 get_Info()

      • vcpu_used: 通过 libvirt 中 dom.vcpus() 从而统计该节点上所有虚拟机 vcpu 总和

    • RAM

      • memory: libvirt 中 get_Info()

      • memory_mb_used:先通过 /proc/meminfo 统计可用内存, 再用总内存减去可用内存得出(资源再统计时会重新计算该值)

    • DISK

      • local_gb: os.statvfs(CONF.instances_path)

      • local_gb_used: os.statvfs(CONF.instances_path)(资源再统计时会重新计算该值)

    • 其它

      • hypervisor 相关信息:均通过 libvirt 获取

      • PCI: libvirt 中 listDevices(‘pci’, 0)

      • NUMA: livirt 中 getCapabilities()

    那么问题来了,按照上述收集资源的方式,free_ram_mb, free_disk_gb 不可能为负数。Nova-compute 在上报资源至数据库前,还根据该节点上的虚拟机又做了一次资源统计。

    为什么需再次统计 RAM 资源?宿主机的内存不只是分配给虚拟机,还有肩负其他应用,因此必须重新统计 RAM 资源。

    统计的方式为:

    free_memory = total_memory - CONF.reserved_host_memory_mb - 虚拟机理论内存总和
    CONF.reserved_host_memory_mb:内存预留,比如预留给系统或其它应用
    虚拟机理论内存总和:即所有虚拟机 flavor 中的内存总和 free_disk_gb = local_gb - CONF.reserved_host_disk_mb / 1024 - 虚拟机理论磁盘总和
    nova.scheduler.filters.ram_filter.BaseRamFilter
    class BaseRamFilter(filters.BaseHostFilter):
     
        def host_passes(self, host_state, spec_obj):
            """Only return hosts with sufficient available RAM."""
            requested_ram = spec_obj.memory_mb
            free_ram_mb = host_state.free_ram_mb
            total_usable_ram_mb = host_state.total_usable_ram_mb
     
            if not total_usable_ram_mb >= requested_ram:
                LOG.debug("%(host_state)s does not have %(requested_ram)s MB "
                          "usable ram before overcommit, it only has "
                          "%(usable_ram)s MB.",
                          {'host_state': host_state,
                           'requested_ram': requested_ram,
                           'usable_ram': total_usable_ram_mb})
                return False
     
            ram_allocation_ratio = self._get_ram_allocation_ratio(host_state,
                                                                  spec_obj)
     
            memory_mb_limit = total_usable_ram_mb * ram_allocation_ratio
            used_ram_mb = total_usable_ram_mb - free_ram_mb
            usable_ram = memory_mb_limit - used_ram_mb
            if not usable_ram >= requested_ram:
                LOG.debug("%(host_state)s does not have %(requested_ram)s MB "
                        "usable ram, it only has %(usable_ram)s MB usable ram.",
                        {'host_state': host_state,
                         'requested_ram': requested_ram,
                         'usable_ram': usable_ram})
                return False
     
            host_state.limits['memory_mb'] = memory_mb_limit
            return True

    为什么要重新统计 DISK 资源?原因与 RAM 大致相同。为了节省空间, qemu-kvm 常用 QCOW2 格式镜像,以创建 DISK 大小为 100G 的虚拟机为例,虚拟机创建后,其镜像文件往往只有几百 KB,当有大量数据写入时磁盘时,宿主机上对应的虚拟机镜像文件会迅速增大。而 os.statvfs 统计的是虚拟机磁盘当前使用量,并不能反映潜在使用量。因此必须重新统计 DISK 资源。

    统计的方式为:

     free_disk_gb = local_gb - CONF.reserved_host_disk_mb / 1024 - 虚拟机理论磁盘总和

    CONF.reserved_host_disk_mb:磁盘预留

    虚拟机理论磁盘总和:即所有虚拟机  flavor 中得磁盘总和
    nova.scheduler.filters.disk_filter.DiskFilter
    class DiskFilter(filters.BaseHostFilter)::
        def _get_disk_allocation_ratio(self, host_state, spec_obj):
        return host_state.disk_allocation_ratio
     
    def host_passes(self, host_state, spec_obj):
        """Filter based on disk usage."""
        requested_disk = (1024 * (spec_obj.root_gb +
                                  spec_obj.ephemeral_gb) +
                          spec_obj.swap)
     
        free_disk_mb = host_state.free_disk_mb
        total_usable_disk_mb = host_state.total_usable_disk_gb * 1024
         
        if total_usable_disk_mb < requested_disk:
        LOG.debug("%(host_state)s does not have %(requested_disk)s "
                  "MB usable disk space before overcommit, it only "
                  "has %(physical_disk_size)s MB.",
                  {'host_state': host_state,
                   'requested_disk': requested_disk,
                   'physical_disk_size':
                       total_usable_disk_mb})
        return False
        disk_allocation_ratio = self._get_disk_allocation_ratio(
        host_state, spec_obj)
     
        disk_mb_limit = total_usable_disk_mb * disk_allocation_ratio
        used_disk_mb = total_usable_disk_mb - free_disk_mb
        usable_disk_mb = disk_mb_limit - used_disk_mb
      
        if not usable_disk_mb >= requested_disk:
        LOG.debug("%(host_state)s does not have %(requested_disk)s MB "
                "usable disk, it only has %(usable_disk_mb)s MB usable "
                "disk.", {'host_state': host_state,
                           'requested_disk': requested_disk,
                           'usable_disk_mb': usable_disk_mb})
            return False
     
        disk_gb_limit = disk_mb_limit / 1024
        host_state.limits['disk_gb'] = disk_gb_limit
        return True

    资源超配与调度

    即使 free_ram_mb 或 free_disk_gb 为负,虚拟机依旧有可能创建成功。事实上,当 nova-scheduler 在调度过程中,某些 filter 允许资源超配,比如 CPU、RAM 和 DISK 等 filter,它们默认的超配比为:

    • CPU: CONF.cpu_allocation_ratio = 16

    • RAM: CONF.ram_allocation_ratio = 1.5

    • DISK: CONF.disk_allocation_ratio = 1.0

    以 ram_filter 为例,在根据 RAM 过滤宿主机时,过滤的原则为:

    memory_limit = total_memory * ram_allocation_ratio
    used_memory = total_memory - free_memory
    memory_limit - used_memory < flavor['ram'],表示内存不足,过滤该宿主机;否则保留该宿主机。

    宿主机 RAM 和 DISK 的使用率往往要小于虚拟机理论使用的 RAM 和 DISK,在剩余资源充足的条件下,libvirt 将成功创建虚拟机。

    内存和磁盘超配虽然能提供更多数量的虚拟机,当该宿主机上大量虚拟机的负载都很高时,轻着影响虚拟机性能,重则引起 qemu-kvm 相关进程被杀,即虚拟机被关机。

    因此对于线上稳定性要求高的业务,建议不要超配 RAM 和 DISK,但可适当超配 CPU。建议这几个参数设置为:

    • CPU: CONF.cpu_allocation_ratio = 4

    • RAM: CONF.ram_allocation_ratio = 1.0

    • DISK: CONF.disk_allocation_ratio = 1.0

    • RAM-Reserve: CONF.reserved_host_memory_mb = 2048

    • DISK-Reserve: CONF.reserved_host_disk_mb = 20480

  • 相关阅读:
    循环
    pl/sql小结
    poi编程
    Activiti工作流面试相关知识!
    工作流学习——Activiti流程变量五步曲
    工作流学习——Activiti流程实例、任务管理四步曲
    工作流学习——Activiti流程定义管理三步曲
    工作流学习——Activiti整体认识二步曲
    工作流学习——重要概念扫盲篇一步曲
    Activiti工作流数据库表详细介绍(23张表)
  • 原文地址:https://www.cnblogs.com/gushiren/p/9512016.html
Copyright © 2011-2022 走看看