searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

kubevirt虚机支持大页内存和Numa绑定

2023-10-20 06:41:49
81
0

一、Hupe Page 定义

在 Linux 中,虚机内存是以页为单位来管理的。页的大小为 4KB。 1MB 的内存能划分为 256 页; 1GB 则等同于 256000 页。

CPU 中有一个内置的内存管理单元,用于存储这些页的列表(页表),每页都有一个对应的入口。

TLB(Translation lookaside buffer)为页表(存放虚拟地址的页地址和物理地址的页地址的映射关系)在CPU内部的高速缓存。TLB的命中率越高,页表查询性能就越好。

TLB的一行为一个页的映射关系,也就是管理了一个页大小的内存:TLB管理的内存大小 = TLB行数 x 内存的页大小

同一个CPU的TLB行数固定,因此内存页越大,管理的内存越大,相同业务场景下的TLB命中率就越高。

如果为服务器分配的内存远大于现有内存管理单元能管理的量,则会造成内存的浪费。 CentOS 6 中为解决这个问题,使用了大页面(Huge Page)的方式。

简单来说,大页面(Huge Page)即大小为 2MB 或者 1GB 的页。 2MB 的页适用于管理 GB 级单位的内存; 1GB 的页适用于 TB 级单位的内存。

大页面(Hupe Page)的配置

大页面配置需要连续的内存空间,因此在开机时就分配是最可靠的方式。配置大页面的参数有:

  • hugepages :在内核中定义了开机启动时就分配的永久大页面的数量。默认为 0,即不分配。只有当系统有足够的连续可用页时,分配才会成功。由该参数保留的页不能用于其他用途。

hugepagesz: 在内核中定义了开机启动时分配的大页面的大小。可选值为 2MB 和 1GB 。默认是 2MB 。

default_hugepagesz:在内核中定义了开机启动时分配的大页面的默认大小。

1、开机时就分配方式:

# cat /etc/default/grub

GRUB_TIMEOUT=5

GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"

GRUB_DEFAULT=saved

GRUB_DISABLE_SUBMENU=true

GRUB_TERMINAL_OUTPUT="console"

GRUB_CMDLINE_LINUX="crashkernel=auto rhgb quiet mgag200.modeset=0 transparent_hugepage=never default_hugepagesz=2M hugepagesz=2M hugepages=1024"

GRUB_DISABLE_RECOVERY="true"

 

# grub2-mkconfig -o /boot/grub2/grub.cfg

# reboot

 

2、动态设置方式:

# echo never > /sys/kernel/mm/transparent_hugepage/enabled

# echo 1024 > /proc/sys/vm/nr_hugepages

# systemctl restart kubelet

 

# 验证是否生效,刚到HugePages_Total和HugePages_Free有值就生效了

# cat /proc/meminfo | grep -i huge

AnonHugePages:   3534848 kB

ShmemHugePages:        0 kB

FileHugePages:         0 kB

HugePages_Total:    1024

HugePages_Free:     1024

HugePages_Rsvd:        0

HugePages_Surp:        0

Hugepagesize:       2048 kB

Hugetlb:         2097152 kB

# cat /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages

512

# cat /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages

512

# cat /sys/devices/system/node/node1/hugepages/hugepages-1048576kB/nr_hugepages

0

# cat /sys/devices/system/node/node0/hugepages/hugepages-1048576kB/nr_hugepages

0

配置大页面后,系统在开机启动时会首选尝试在内存中找到并预留连续的大小为 hugepages * hugepagesz 的内存空间。如果内存空间不满足,则启动会报错 Kernel Panic, Out of Memory 等错误。
使用大页面后,能减少系统管理和访问页的时间;内核中的 swap 守护进程也不会管理大页面占用的这部分空间。合理设置大页面能减少内存操作的负担,减少访问页表造成性能瓶颈的可能性,从而提升系统性能。

注意:节点从普通内存分出一定大小来作为大页内存使用,所以节点分配了大页内存后,节点的普通内存总库存大小要减去大页内存的值,这个重启kubelet后node的Allocatable.Memory会自动减掉,只需要在OPS重新同步内存库存。

二、创建HugePage虚机

虚机要同时满足以下条件:

resources.limits.memory的值必须等于resources.requests.memory。

resources.requests.memory的值不能超过节点的2MB 或者 1GB 的页总大小(页总大小=hugepages * hugepagesz)。

如果选的页大小是2MB,resources.requests.memory的值必须可以整除2MB,如果选的页大小是1GB,resources.requests.memory的值必须可以整除1GB。

apiVersion: kubevirt.io/v1alpha3

kind: VirtualMachine

metadata:

  labels:

    kubevirt.io/vm: huge-page-vm

  name: huge-page-vm

  # namespace: test

spec:

  template:

    spec:

      domain:

        cpu:

          cores: 2

          model: host-model

        resources:

          limits:

            cpu: "2"

            memory: 4Gi

          requests:

            cpu: 666m

            memory: 4Gi

        memory:

          # 设置hugepagesz是2Mi或1Gi

          hugepages:

            pageSize: "2Mi"

virt-launcher的pod会占用多一点内存,所以huge-page虚机扣减库存多加1G大小。

注意:mem_huge_page_repo表更新allocate_memory时,mem__huge_page_sale表的记录插入时,allocate_request和allocate_limit的值应该比request和limit值大1G。

 

三、NUMA支持

NUMA简单可以理解为CPU的内存亲和性,在Linux内核2.5版本开始支持。不同NUMA内的CPU core访问同一个位置的内存,性能不同。内存访问延时从高到低为:跨CPU > 跨NUMA不跨CPU > NUMA内。

要开出NUMA的虚机,必须满足以下条件:

  • 虚机必须是独占CPU的,虚机必须是Guaranteed级别。
  • 节点必须配置了大页内存。
  • kubevirt 版本是0.43以上,feature-gate必须打开NUMA特性。

apiVersion: kubevirt.io/v1alpha3

kind: VirtualMachine

metadata:

  labels:

    kubevirt.io/vm: numa-vm

  name: numa-vm

  # namespace: test

spec:

  template:

    spec:

      domain:

        cpu:

          dedicatedCpuPlacement: true

          isolateEmulatorThread: true

          numa:

            guestMappingPassthrough: { }

        resources:

          limits:

            cpu: 2

            memory: 4Gi

          requests:

            cpu: 2

            memory: 4Gi

        memory:

          # 设置hugepagesz是2Mi或1Gi

          hugepages:

            pageSize: "2Mi"

kubevrit文档不建议domain.cpu和resources.cpu同时设置,我们统一使用resources设置cpu和内存即可。

0条评论
0 / 1000
魏****生
3文章数
0粉丝数
魏****生
3 文章 | 0 粉丝
魏****生
3文章数
0粉丝数
魏****生
3 文章 | 0 粉丝
原创

kubevirt虚机支持大页内存和Numa绑定

2023-10-20 06:41:49
81
0

一、Hupe Page 定义

在 Linux 中,虚机内存是以页为单位来管理的。页的大小为 4KB。 1MB 的内存能划分为 256 页; 1GB 则等同于 256000 页。

CPU 中有一个内置的内存管理单元,用于存储这些页的列表(页表),每页都有一个对应的入口。

TLB(Translation lookaside buffer)为页表(存放虚拟地址的页地址和物理地址的页地址的映射关系)在CPU内部的高速缓存。TLB的命中率越高,页表查询性能就越好。

TLB的一行为一个页的映射关系,也就是管理了一个页大小的内存:TLB管理的内存大小 = TLB行数 x 内存的页大小

同一个CPU的TLB行数固定,因此内存页越大,管理的内存越大,相同业务场景下的TLB命中率就越高。

如果为服务器分配的内存远大于现有内存管理单元能管理的量,则会造成内存的浪费。 CentOS 6 中为解决这个问题,使用了大页面(Huge Page)的方式。

简单来说,大页面(Huge Page)即大小为 2MB 或者 1GB 的页。 2MB 的页适用于管理 GB 级单位的内存; 1GB 的页适用于 TB 级单位的内存。

大页面(Hupe Page)的配置

大页面配置需要连续的内存空间,因此在开机时就分配是最可靠的方式。配置大页面的参数有:

  • hugepages :在内核中定义了开机启动时就分配的永久大页面的数量。默认为 0,即不分配。只有当系统有足够的连续可用页时,分配才会成功。由该参数保留的页不能用于其他用途。

hugepagesz: 在内核中定义了开机启动时分配的大页面的大小。可选值为 2MB 和 1GB 。默认是 2MB 。

default_hugepagesz:在内核中定义了开机启动时分配的大页面的默认大小。

1、开机时就分配方式:

# cat /etc/default/grub

GRUB_TIMEOUT=5

GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"

GRUB_DEFAULT=saved

GRUB_DISABLE_SUBMENU=true

GRUB_TERMINAL_OUTPUT="console"

GRUB_CMDLINE_LINUX="crashkernel=auto rhgb quiet mgag200.modeset=0 transparent_hugepage=never default_hugepagesz=2M hugepagesz=2M hugepages=1024"

GRUB_DISABLE_RECOVERY="true"

 

# grub2-mkconfig -o /boot/grub2/grub.cfg

# reboot

 

2、动态设置方式:

# echo never > /sys/kernel/mm/transparent_hugepage/enabled

# echo 1024 > /proc/sys/vm/nr_hugepages

# systemctl restart kubelet

 

# 验证是否生效,刚到HugePages_Total和HugePages_Free有值就生效了

# cat /proc/meminfo | grep -i huge

AnonHugePages:   3534848 kB

ShmemHugePages:        0 kB

FileHugePages:         0 kB

HugePages_Total:    1024

HugePages_Free:     1024

HugePages_Rsvd:        0

HugePages_Surp:        0

Hugepagesize:       2048 kB

Hugetlb:         2097152 kB

# cat /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages

512

# cat /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages

512

# cat /sys/devices/system/node/node1/hugepages/hugepages-1048576kB/nr_hugepages

0

# cat /sys/devices/system/node/node0/hugepages/hugepages-1048576kB/nr_hugepages

0

配置大页面后,系统在开机启动时会首选尝试在内存中找到并预留连续的大小为 hugepages * hugepagesz 的内存空间。如果内存空间不满足,则启动会报错 Kernel Panic, Out of Memory 等错误。
使用大页面后,能减少系统管理和访问页的时间;内核中的 swap 守护进程也不会管理大页面占用的这部分空间。合理设置大页面能减少内存操作的负担,减少访问页表造成性能瓶颈的可能性,从而提升系统性能。

注意:节点从普通内存分出一定大小来作为大页内存使用,所以节点分配了大页内存后,节点的普通内存总库存大小要减去大页内存的值,这个重启kubelet后node的Allocatable.Memory会自动减掉,只需要在OPS重新同步内存库存。

二、创建HugePage虚机

虚机要同时满足以下条件:

resources.limits.memory的值必须等于resources.requests.memory。

resources.requests.memory的值不能超过节点的2MB 或者 1GB 的页总大小(页总大小=hugepages * hugepagesz)。

如果选的页大小是2MB,resources.requests.memory的值必须可以整除2MB,如果选的页大小是1GB,resources.requests.memory的值必须可以整除1GB。

apiVersion: kubevirt.io/v1alpha3

kind: VirtualMachine

metadata:

  labels:

    kubevirt.io/vm: huge-page-vm

  name: huge-page-vm

  # namespace: test

spec:

  template:

    spec:

      domain:

        cpu:

          cores: 2

          model: host-model

        resources:

          limits:

            cpu: "2"

            memory: 4Gi

          requests:

            cpu: 666m

            memory: 4Gi

        memory:

          # 设置hugepagesz是2Mi或1Gi

          hugepages:

            pageSize: "2Mi"

virt-launcher的pod会占用多一点内存,所以huge-page虚机扣减库存多加1G大小。

注意:mem_huge_page_repo表更新allocate_memory时,mem__huge_page_sale表的记录插入时,allocate_request和allocate_limit的值应该比request和limit值大1G。

 

三、NUMA支持

NUMA简单可以理解为CPU的内存亲和性,在Linux内核2.5版本开始支持。不同NUMA内的CPU core访问同一个位置的内存,性能不同。内存访问延时从高到低为:跨CPU > 跨NUMA不跨CPU > NUMA内。

要开出NUMA的虚机,必须满足以下条件:

  • 虚机必须是独占CPU的,虚机必须是Guaranteed级别。
  • 节点必须配置了大页内存。
  • kubevirt 版本是0.43以上,feature-gate必须打开NUMA特性。

apiVersion: kubevirt.io/v1alpha3

kind: VirtualMachine

metadata:

  labels:

    kubevirt.io/vm: numa-vm

  name: numa-vm

  # namespace: test

spec:

  template:

    spec:

      domain:

        cpu:

          dedicatedCpuPlacement: true

          isolateEmulatorThread: true

          numa:

            guestMappingPassthrough: { }

        resources:

          limits:

            cpu: 2

            memory: 4Gi

          requests:

            cpu: 2

            memory: 4Gi

        memory:

          # 设置hugepagesz是2Mi或1Gi

          hugepages:

            pageSize: "2Mi"

kubevrit文档不建议domain.cpu和resources.cpu同时设置,我们统一使用resources设置cpu和内存即可。

文章来自个人专栏
边缘云主机
3 文章 | 2 订阅
0条评论
0 / 1000
请输入你的评论
0
0