Too young, too simple. Sometimes, naive & stupid

配置大内存页

有个两种方法可以保留大内存页:

  1. at boot time(启动时修改)
  2. at run time(运行时修改)

在 启动时保留会增加成功的可能性,因为内存尚未明显碎片化。但是在NUMA架构上,页面数量会自动在NUMA节点之间分配。运行时修改允许为每个NUMA节点保留大内存页。如果在引导过程中今早完成运行时预留,则内存碎片的可能性会降低。

引导时配置大内存页

要在引导时配置大内存页,请将以下参数添加到内核引导命令行:

  • hugepages

    定义引导时在内核中配置的持久性大内存页的数量。默认值为0,如果系统中有足够的连续物理空闲页面,则只能分配大内存页。此参数保留的页不能用于其他目的。

    通过修改proc/sys/vm/nr_hugepages文件的值在引导后使用。

    在NUMA系统中,使用此参数分配的大内存页在节点之间平均分配。可以通过更改节点的值在运行时将大内存页分配给特定节点的/sys/devices/system/node/NODE_ID/hugepages/hugepages-1048576kB/nr_hugepages文件。

  • hugepagesz

    定义引导时在内核中配置的持久页面大小。有效值为2MB和1GB。默认为2MB。

    例如,保留1GB页面

    HugeTLB子系统支持的页面大小取决于体系结构。在x86_64架构上,支持2MB大内存也和1GB大内存页。

    1. 通过将以下行附加到内核命令 ,为1GB页面创建HugeTLB池:

      1
      default_hugepagesz=1G hugepagesz=1G
    2. 创建一个名为/usr/lib/systemd/system/hugetlb-gigantic-pages.service,具体内容如下:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      [Unit]
      Description=HugeTLB Gigantic Pages Reservation
      DefaultDependencies=no
      Before=dev-hugepages.mount
      ConditionPathExists=/sys/devices/system/node
      ConditionKernelCommandLine=hugepagesz=1G

      [Service]
      Type=oneshot
      RemainAfterExit=yes
      ExecStart=/usr/lib/systemd/hugetlb-reserve-pages.sh

      [Install]
      WantedBy=sysinit.target
    3. 创建一个名为/usr/lib/systemd/hugetlb-reserve-pages.sh具体内容:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      #!/bin/sh

      nodes_path=/sys/devices/system/node/
      if [ ! -d $nodes_path ]; then
      echo "ERROR: $nodes_path does not exist"
      exit 1
      fi

      reserve_pages()
      {
      echo $1 > $nodes_path/$2/hugepages/hugepages-1048576kB/nr_hugepages
      }

      reserve_pages NUMBER_OF_PAGES node

      将最后一行的NUMBER_OF_PAGES替换为要爆了的1GB页数,并将节点替换为要保留这些页的节点名称。

    4. 要在node0上保留两个1GB页面,在node1上保留一个1GB页,用以下代码替换最后一行:

      1
      2
      reserve_pages 2 node0
      reserve_pages 1 node1

      可以根据需要对其进行修改,也可以添加更多行以在其他节点中保留。

    5. 使脚本执行:

      1
      chmod +x /usr/lib/systemd/hugetlb-reserve-pages.sh
    6. 启用:

      1
      systemctl enable hugetlb-gigantic-pages

可以随时通过写入nr_hugepages尝试在运行时保留更多1GB页面。但是,由于内存碎片,此类预留可能会失败。保留1GB页面的最可靠方法是使用此脚本,该脚本在早期启动时运行。

运行时配置大内存页

使用以下参数可以在运行时影响大型页:

/sys/devices/system/node/NODE_ID/hugepages/HUGEPAGES-SIZE/nr_hugepages定义分配给指定NUMA节点的指定大内存页数,以下示例是将20个2048KB的大页移动到node2

1
2
3
4
5
6
7
8
9
10
11
12
13
numastat -cm | egrep 'Node|Huge'
Node 0 Node 1 Node 2 Node 3 Total add
AnonHugePages 0 2 0 8 10
HugePages_Total 0 0 0 0 0
HugePages_Free 0 0 0 0 0
HugePages_Surp 0 0 0 0 0
echo 20 > /sys/devices/system/node/node2/hugepages/hugepages-2048kB/nr_hugepages
numastat -cm | egrep 'Node|Huge'
Node 0 Node 1 Node 2 Node 3 Total
AnonHugePages 0 2 0 8 10
HugePages_Total 0 0 40 0 40
HugePages_Free 0 0 40 0 40
HugePages_Surp 0 0 0 0 0

/proc/sys/vm/nr_overcommit_hugepages定义系统通过过度使用内存而异创建和使用的其他大内存页的最大数。将任何非零值写入此文件表示如果持久性大页池耗尽,系统将从内核的正常内存页池中湖区大量页面。当这些剩余的大内存页空闲时,他们将被释放会内核的正常页面池。