• OpenStack 高性能虚拟机之大页内存


    目录

    前文列表

    多进程、多线程与多处理器计算平台的性能问题
    OpenStack 高性能虚拟机之 CPU 绑定
    OpenStack 高性能虚拟机之 NUMA 亲和

    Nova 虚拟机的大页内存设置

    绝大多数现代 CPU 都支持多种内存页尺寸,从 4KB 到 2M/4M,最大可以达到 1GB。所有 CPU 都默认使用最小的 4KB 页,如果具有较大的内存可以选择启用大页内存进行分配,这将会明显减少 CPU 的页表项,因此会增加 TLB 页表缓存的命中率,降低内存访问延迟。如果操作系统使用默认的小页内存,随着运行时间,系统会出现越来越多的碎片,以至于后来难以申请到大页的内存。在大页内存大小越大时,该问题越严重。因此,如果当你有使用大页内存的需求时,最好的办法是在系统启动时就预留好内存空间。当前的 Linux 内核不允许针对特定的 NUMA 节点进行这样的设定,不过,在不久的将来这个限制将被取消。更进一步的限制是,由于 MMIO 空洞的存在,内存开始的 1GB 不能使用 1GB 的大页。

    Linux 内核已经支持 THP(Transparent Huge Pages,透明巨型页)特性,该特性会尝试为应用程序预分配大页内存。依赖该特性的一个问题是,虚拟机的拥有者并不能保证给虚拟机使用的是大页内存还是小页内存。

    内存块是直接指定给特定的 NUMA 单元的,这就意味着大页内存也是直接指定在 NUMA 单元上的。因此在 NUMA 单元上分配虚拟机时,计算服务需要考虑在 NUMA 单元或者主机上可能会用到的大页内存。为虚拟机内存启用大页内存时,可以不用考虑虚拟机操作系统是否会使用。

    Linux 内核有一项特性,叫做内核共享存储(KSM),该特性使得不同的 CPU 可以共享相同内容的内存页。内核会主动扫描内存,合并内容相同的内存页。如果有 CPU 改变这个共享的内存页时,会采用写时复制(COW)的方式写入新的内存页。当一台主机上的多台虚拟机使用相同操作系统或者虚拟机使用很多相同内容内存页时,KSM 可以显著提高内存的利用率。因为内存扫描的消耗,使用 KSM 的代价是增加了 CPU 的负载,并且如果虚拟机突然做写操作时,会引发大量共享的页面,此时会存在潜在的内存压力峰值。虚拟化管理层必须因此积极地监控内存压力情况并做好现有虚拟机迁移到其他主机的准备,如果内存压力超过一定的水平限制,将会引发大量不可预知的 Swap 操作,甚至引发 OOM。所以在性能要求严格的场景中,我们建议关闭内存共享特性。

    计算节点可以配置 CPU 与内存的超配比例,但是一旦使用了大页内存,内存便不能再进行超配。因为当使用大页内存时,虚拟机内存页必须与主机内存页一一映射,并且主机操作系统能通过 Swap 分区分配大页内存,这也排除了内存超配的可能。大页内存的使用,意味着需要支持内存作为专用资源的虚拟机类型。

    尽管设置专用资源时,不会超配内存与 CPU,但是 CPU 与内存的资源仍然需要主机操作系统提前预留。如果使用大页内存,必须在主机操作系统中明确预留。对于 CPU 则有一些灵活性。因为尽管使用专用资源绑定 CPU,主机操作系统依然会使用这些 CPU 的一些时间。不管怎么样,最好可以预留一定的物理 CPU 专门为主机操作系统服务,以避免操作系统过多占用虚拟机 CPU,而造成对虚拟机性能的影响。Nova可以保留一部分 CPU 专门为操作系统服务,这部分功能将会在后续的设计中加强。

    允许内存超配时,超出主机内存的部分将会使用到 Swap。ZSWAP 特性允许压缩内存页被写入 Swap 设备,这样可以大量减少 Swap 设备的 I/O 执行,减少了交换主机内存页面中固有的性能下降。Swap 会影响主机整体 I/O 性能,所以尽量不要把需要专用内存的虚拟机机与允许内存超配的虚拟机放在同一台物理主机上。如果专用 CPU 的虚拟机与允许超配的虚拟机竞争 CPU,由于 Cache 的影响,将会严重影响专用 CPU 的虚拟机的性能,特别在同一个 NUMA 单元上时。因此,最好将使用专用 CPU 的虚拟机与允许超配的虚拟机放在不同的主机上,其次是不同的 NUMA 单元上。

    关于虚拟机在主机上的 CPU 与内存的布局决策,也会影响其他的主机资源分配。例如,PCI 设备与 NUMA 单元关系密切,PCI 设备的 DMA 操作使用的内存最好在本地 NUMA 单元上。因此,在哪个 NUMA 单元上分配虚拟机,将会影响到 PCI 设备的分配。

    Nova 内存页设置

    openstack flavor set FLAVOR-NAME 
        --property hw:mem_page_size=PAGE_SIZE

    PAGE_SIZE

    • small (default):使用最小的 page size,e.g. x86 平台的 4KB。

    • large:只使用最大的 page size,e.g. x86 平台的 2MB 或 1GB。

    • any:取决于 Hypervisor 类型。如果是 Libvirt 的话,会根据服务器的大页内存设置进行决策,优先使用大的大页,依次递减。

    • pagesize:指定具体的 pape size,e.g. 4KB、2MB、2048、1GB。

    e.g.

    openstack flavor create --vcpus 2 --ram 2048 --disk 40 
        --property hw:mem_page_size=2MB Flavor1
    
    openstack flavor create --vcpus 2 --ram 2048 --disk 40 
        --property hw:mem_page_size=1GB Flavor2

    NOTE:Large pages can be enabled for guest RAM without any regard to whether the guest OS will use them or not. If the guest OS chooses not to use huge pages, it will merely see small pages as before. Conversely, if a guest OS does intend to use huge pages, it is very important that the guest RAM be backed by huge pages. Otherwise, the guest OS will not be getting the performance benefit it is expecting.

    手动为 KVM 虚拟机中设置大页内存(http://www.linux-kvm.org/page/UsingLargePages)

    # 2G 内存设置 256
    # 4G 内存设置 512
    # 8G 内存设置 1024
    
    echo 1024 > /proc/sys/vm/nr_hugepages

    实战经验

    1. 大页内存要求内存页对齐,即 Flavor RAM 可以被 hw:mem_page_size 整除(单位为 kb)。e.g.
    openstack flavor create --vcpus 2 --ram 2048 --disk 40 
        --property hw:mem_page_size=1GB Flavor2
    
    # 当 hw:mem_page_size=1GB 时,RAM 必须为 1024 的倍数
    1. 宿主机的大页面是平均分到每个 NUMA 节点上的,除非某个 NUMA 节点本身没有足够的可用连续内存来生成大页面,那么此时大页面将由另外一个 NUMA 节点生成。通过 /proc/sys/vm/nr_hugepages_mempolicy 可以指定大页面具体由哪个 NUMA 节点来生成。查看 NUMA 节点的大页面资源,e.g.
    # 当大页面的总数为 256,有 2 个 NUMA 节点时,那么每个 NUMA 节点的大页数为 256/2 = 128 个
    
    $ cat /sys/devices/system/node/node*/meminfo | fgrep Huge
    Node 0 AnonHugePages:    120832 kB
    Node 0 HugePages_Total:   128
    Node 0 HugePages_Free:    127
    Node 0 HugePages_Surp:      0
    Node 1 AnonHugePages:         0 kB
    Node 1 HugePages_Total:   128
    Node 1 HugePages_Free:    127
    Node 1 HugePages_Surp:      0
    1. 大页面数量与单个大页面容量的乘积就是某个 NUMA 节点的大页容量。当 Flavor 的 RAM 大于单个 NUMA 节点的 Free Huge Page Size 时,需要将 Flavor RAM 分配到不同的 NUMA 节点上。否则,虚拟机会应该资源不足而创建失败。e.g.
    openstack flavor set <FLAVOR>  
      --property hw:numa_nodes=2  
      --property hw:numa_cpus.0=0  
      --property hw:numa_cpus.1=1,2,3  
      --property hw:numa_mem.0=1024  
      --property hw:numa_mem.1=3072 

    参考文档

    https://www.ibm.com/developerworks/cn/linux/l-cn-hugetlb/index.html

    相关阅读:

  • 相关阅读:
    谷粒学院项目P108集添加课程信息接口时的一个坑
    vue下拉框属性说明
    mybatisplus查询时间段内的报表(月报等)
    UI自动化,换种思路,把执行步骤换成动图gif
    以OD机考为名,python学习之路
    牛客网刷题按题目难度排:简单
    正则表达式随用随记
    第十四章 论一只爬虫的自我修养
    在低版本Android中使用Java Stream功能
    Yolov5训练自有模型
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13309612.html
Copyright © 2020-2023  润新知