검색

14.5. 가상 머신 CPU 성능 최적화

download PDF

호스트 시스템의 물리적 CPU와 마찬가지로 vCPU는 VM(가상 시스템) 성능에 매우 중요합니다. 결과적으로 vCPU를 최적화하면 VM의 리소스 효율성에 큰 영향을 미칠 수 있습니다. vCPU를 최적화하려면 다음을 수행합니다.

  1. VM에 할당된 호스트 CPU 수를 조정합니다. CLI 또는 웹 콘솔을 사용하여 이 작업을 수행할 수 있습니다.
  2. vCPU 모델이 호스트의 CPU 모델과 일치하는지 확인합니다. 예를 들어 호스트의 CPU 모델을 사용하도록 testguest1 VM을 설정하려면 다음을 수행합니다.

    # virt-xml testguest1 --edit --cpu host-model
  3. KSM(커널 동일 페이지 병합)을 비활성화합니다.
  4. 호스트 시스템에서 NUMA(Non-Uniform Memory Access)를 사용하는 경우 해당 VM에 NUMA를 구성할 수도 있습니다. 이를 통해 호스트의 CPU 및 메모리 프로세스를 가능한 VM의 CPU 및 메모리 프로세스에 긴밀하게 매핑합니다. 실제로 NUMA 튜닝은 VM에 할당된 시스템 메모리에 대한 보다 능률적인 액세스를 제공하므로 vCPU 처리 효율성이 향상될 수 있습니다.

    자세한 내용은 가상 머신에서 NUMA 구성샘플 vCPU 성능 튜닝 시나리오를 참조하십시오.

14.5.1. 명령줄 인터페이스를 사용하여 가상 CPU 추가 및 제거

VM(가상 머신)의 CPU 성능을 늘리거나 최적화하려면 VM에 할당된 가상 CPU(vCPU)를 추가하거나 제거할 수 있습니다.

실행 중인 VM에서 수행되는 경우 vCPU 핫 플러그 및 핫 플러그 해제라고도 합니다. 그러나 RHEL 8에서는 vCPU 핫 언플러그가 지원되지 않으며 Red Hat은 사용하지 않는 것이 좋습니다.

사전 요구 사항

  • 선택 사항: 대상 VM에서 vCPU의 현재 상태를 확인합니다. 예를 들어 testguest VM의 vCPU 수를 표시하려면 다음을 수행합니다.

    # virsh vcpucount testguest
    maximum      config         4
    maximum      live           2
    current      config         2
    current      live           1

    이 출력은 testguest 가 현재 1 vCPU를 사용 중이며, VM의 성능을 높이기 위해 1개의 vCPu를 핫 플러그로 연결할 수 있음을 나타냅니다. 그러나 재부팅 후 testguest 에서 사용하는 vCPU 수는 2개로 변경되며 2개의 vCPU를 핫 플러그로 연결할 수 있습니다.

절차

  1. VM에 연결할 수 있는 최대 vCPU 수를 조정하여 다음 부팅 시 적용됩니다.

    예를 들어 testguest VM의 최대 vCPU 수를 8로 늘리려면 다음을 수행합니다.

    # virsh setvcpus testguest 8 --maximum --config

    CPU 토폴로지, 호스트 하드웨어, 하이퍼바이저 및 기타 요인에 의해 최대값이 제한될 수 있습니다.

  2. VM에 연결된 현재 vCPU 수를 이전 단계에서 구성한 최대값까지 조정합니다. 예를 들면 다음과 같습니다.

    • 실행 중인 testguest VM에 연결된 vCPU 수를 4로 늘리려면 다음을 수행합니다.

      # virsh setvcpus testguest 4 --live

      이로 인해 VM의 다음 부팅까지 VM의 성능 및 호스트 부하 공간이 testguest 의 호스트 부하가 증가합니다.

    • testguest VM에 연결된 vCPU 수를 영구적으로 1로 줄입니다.

      # virsh setvcpus testguest 1 --config

      이를 통해 VM의 다음 부팅 후 testguest 의 VM 성능 및 호스트 부하 공간이 줄어듭니다. 그러나 필요한 경우 VM에 추가 vCPU를 핫플러그하여 일시적으로 성능을 향상시킬 수 있습니다.

검증

  • VM의 현재 vCPU 상태에 변경 사항이 반영되는지 확인합니다.

    # virsh vcpucount testguest
    maximum      config         8
    maximum      live           4
    current      config         1
    current      live           4

14.5.2. 웹 콘솔을 사용하여 가상 CPU 관리

RHEL 8 웹 콘솔을 사용하면 웹 콘솔이 연결된 VM(가상 머신)에서 사용하는 가상 CPU를 검토하고 구성할 수 있습니다.

사전 요구 사항

절차

  1. RHEL 8 웹 콘솔에 로그인합니다.

    자세한 내용은 웹 콘솔에 로그인 을 참조하십시오.

  2. Virtual Machines (가상 시스템) 인터페이스에서 표시할 정보가 있는 VM을 클릭합니다.

    VM의 그래픽 인터페이스에 액세스하기 위한 선택한 VM 및 콘솔 섹션에 대한 기본 정보가 포함된 Overview(개요) 섹션이 포함된 새 페이지가 열립니다.

  3. Overview(개요) 창에서 vCPU의 수 옆에 있는 Edit( 편집 )를 클릭합니다.

    vCPU 세부 정보 대화 상자가 나타납니다.

    VM CPU 세부 정보 대화 상자를 표시하는 이미지.
  1. 선택한 VM에 대해 가상 CPU를 구성합니다.

    • vCPU 개수 - 현재 사용 중인 vCPU 수입니다.

      참고

      vCPU 수는 vCPU 최대보다 클 수 없습니다.

    • vCPU 최대 - VM에 대해 구성할 수 있는 최대 가상 CPU 수입니다. 이 값이 vCPU 개수 보다 크면 VM에 추가 vCPU를 연결할 수 있습니다.
    • sockets - VM에 표시할 소켓 수입니다.
    • Cores per socket (소켓당 코어 수) - 각 소켓이 VM에 노출될 코어 수입니다.
    • 코어당 스레드 - 각 코어가 VM에 노출될 스레드 수입니다.

      소켓,소켓당 코어, 코어 옵션당 스레드 는 VM의 CPU 토폴로지를 조정합니다. 이는 vCPU 성능에 도움이 될 수 있으며 게스트 OS의 특정 소프트웨어의 기능에 영향을 줄 수 있습니다. 배포에서 다른 설정이 필요하지 않은 경우 기본값을 유지합니다.

  2. Apply(적용)를 클릭합니다.

    VM의 가상 CPU가 구성됩니다.

    참고

    가상 CPU 설정 변경 사항은 VM을 다시 시작한 후에만 적용됩니다.

14.5.3. 가상 머신에서 NUMA 구성

다음 방법을 사용하여 RHEL 8 호스트에서 가상 머신(VM)의 NUMA(Non-Uniform Memory Access) 설정을 구성할 수 있습니다.

사전 요구 사항

  • 호스트는 NUMA 호환 시스템입니다. 이 경우 virsh nodeinfo 명령을 사용하고 NUMA 셀 행 을 참조하십시오.

    # virsh nodeinfo
    CPU model:           x86_64
    CPU(s):              48
    CPU frequency:       1200 MHz
    CPU socket(s):       1
    Core(s) per socket:  12
    Thread(s) per core:  2
    NUMA cell(s):        2
    Memory size:         67012964 KiB

    행의 값이 2 이상이면 호스트는 NUMA와 호환됩니다.

절차

사용하기 쉽도록 자동화된 유틸리티 및 서비스를 사용하여 VM의 NUMA 구성을 설정할 수 있습니다. 그러나 수동 NUMA 설정으로 성능이 크게 향상될 가능성이 높습니다.

자동 방법

  • VM의 NUMA 정책을 Preferred 로 설정합니다. 예를 들어 testguest5 VM에서 이를 수행하려면 다음을 수행합니다.

    # virt-xml testguest5 --edit --vcpus placement=auto
    # virt-xml testguest5 --edit --numatune mode=preferred
  • 호스트에서 자동 NUMA 분산을 활성화합니다.

    # echo 1 > /proc/sys/kernel/numa_balancing
  • numad 서비스를 시작하여 VM CPU를 메모리 리소스에 자동으로 조정합니다.

    # systemctl start numad

수동 방법

  1. 특정 vCPU 스레드를 특정 호스트 CPU 또는 CPU 범위에 고정합니다. 이는 NUMA가 아닌 호스트와 VM에서도 사용할 수 있으며 vCPU 성능을 안전하게 개선하는 방법으로 권장됩니다.

    예를 들어 다음 명령은 각각 CPU 1, 3, 5, 7, 9, 11을 호스팅하도록 testguest6 VM의 0~5 vCPU 스레드를 고정합니다.

    # virsh vcpupin testguest6 0 1
    # virsh vcpupin testguest6 1 3
    # virsh vcpupin testguest6 2 5
    # virsh vcpupin testguest6 3 7
    # virsh vcpupin testguest6 4 9
    # virsh vcpupin testguest6 5 11

    이후에 이 작업이 성공했는지 확인할 수 있습니다.

    # virsh vcpupin testguest6
    VCPU   CPU Affinity
    ----------------------
    0      1
    1      3
    2      5
    3      7
    4      9
    5      11
  2. vCPU 스레드를 고정한 후 지정된 VM과 연결된 QEMU 프로세스 스레드를 특정 호스트 CPU 또는 CPU 범위에 고정할 수도 있습니다. 예를 들어 다음 명령은 testguest6 의 QEMU 프로세스 스레드를 CPU 13 및 15에 고정하고 성공했는지 확인합니다.

    # virsh emulatorpin testguest6 13,15
    # virsh emulatorpin testguest6
    emulator: CPU Affinity
    ----------------------------------
           *: 13,15
  3. 마지막으로 특정 VM에 특히 할당될 호스트 NUMA 노드를 지정할 수도 있습니다. 그러면 VM vCPU에 의해 호스트 메모리 사용량이 향상될 수 있습니다. 예를 들어 다음 명령은 호스트 NUMA 노드 3을 5로 사용하도록 testguest6 를 설정하고 성공했는지 확인합니다.

    # virsh numatune testguest6 --nodeset 3-5
    # virsh numatune testguest6
참고

최상의 성능 결과를 얻으려면 위에 나열된 수동 튜닝 방법을 모두 사용하는 것이 좋습니다.

추가 리소스

14.5.4. 샘플 vCPU 성능 튜닝 시나리오

가능한 한 최상의 vCPU 성능을 얻으려면 다음 시나리오와 같이 수동 vcpupin,emulatorpinnumatune 설정을 함께 사용하는 것이 좋습니다.

시나리오 시작

  • 호스트에는 다음과 같은 하드웨어 세부 사항이 있습니다.

    • NUMA 노드 2개
    • 각 노드의 CPU 코어 3개
    • 각 코어에 두 개의 스레드

    이러한 머신의 virsh nodeinfo 출력은 다음과 유사합니다.

    # virsh nodeinfo
    CPU model:           x86_64
    CPU(s):              12
    CPU frequency:       3661 MHz
    CPU socket(s):       2
    Core(s) per socket:  3
    Thread(s) per core:  2
    NUMA cell(s):        2
    Memory size:         31248692 KiB
  • 기존 VM을 8개의 vCPU로 변경하려고 하므로 단일 NUMA 노드에 맞지 않습니다.

    따라서 각 NUMA 노드에 4개의 vCPU를 배포하고 vCPU 토폴로지가 호스트 토폴로지와 최대한 긴밀하게 일치하도록 해야 합니다. 즉, 지정된 물리적 CPU의 스레드로 실행되는 vCPU는 동일한 코어의 호스트 스레드에 고정되어야 합니다. 자세한 내용은 다음 솔루션을 참조하십시오.

해결책

  1. 호스트 토폴로지에 대한 정보를 가져옵니다.

    # virsh capabilities

    출력에는 다음과 유사한 섹션이 포함되어야 합니다.

    <topology>
      <cells num="2">
        <cell id="0">
          <memory unit="KiB">15624346</memory>
          <pages unit="KiB" size="4">3906086</pages>
          <pages unit="KiB" size="2048">0</pages>
          <pages unit="KiB" size="1048576">0</pages>
          <distances>
            <sibling id="0" value="10" />
            <sibling id="1" value="21" />
          </distances>
          <cpus num="6">
            <cpu id="0" socket_id="0" core_id="0" siblings="0,3" />
            <cpu id="1" socket_id="0" core_id="1" siblings="1,4" />
            <cpu id="2" socket_id="0" core_id="2" siblings="2,5" />
            <cpu id="3" socket_id="0" core_id="0" siblings="0,3" />
            <cpu id="4" socket_id="0" core_id="1" siblings="1,4" />
            <cpu id="5" socket_id="0" core_id="2" siblings="2,5" />
          </cpus>
        </cell>
        <cell id="1">
          <memory unit="KiB">15624346</memory>
          <pages unit="KiB" size="4">3906086</pages>
          <pages unit="KiB" size="2048">0</pages>
          <pages unit="KiB" size="1048576">0</pages>
          <distances>
            <sibling id="0" value="21" />
            <sibling id="1" value="10" />
          </distances>
          <cpus num="6">
            <cpu id="6" socket_id="1" core_id="3" siblings="6,9" />
            <cpu id="7" socket_id="1" core_id="4" siblings="7,10" />
            <cpu id="8" socket_id="1" core_id="5" siblings="8,11" />
            <cpu id="9" socket_id="1" core_id="3" siblings="6,9" />
            <cpu id="10" socket_id="1" core_id="4" siblings="7,10" />
            <cpu id="11" socket_id="1" core_id="5" siblings="8,11" />
          </cpus>
        </cell>
      </cells>
    </topology>
  2. 선택 사항: 해당 툴 및 유틸리티 를 사용하여 VM의 성능을 테스트합니다.
  3. 호스트에 1GiB 대규모 페이지를 설정하고 마운트합니다.

    참고

    ARM 64 호스트와 같은 일부 아키텍처 및 구성에서 1GiB 대규모 페이지를 사용할 수 없습니다.

    1. 호스트의 커널 명령줄에 다음 행을 추가합니다.

      default_hugepagesz=1G hugepagesz=1G
    2. 다음 콘텐츠를 사용하여 /etc/systemd/system/hugetlb-gigantic-pages.service 파일을 만듭니다.

      [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=/etc/systemd/hugetlb-reserve-pages.sh
      
      [Install]
      WantedBy=sysinit.target
    3. 다음 콘텐츠를 사용하여 /etc/systemd/hugetlb-reserve-pages.sh 파일을 만듭니다.

      #!/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 4 node1
      reserve_pages 4 node2

      그러면 node1에서 4GiB의 대규모 페이지와 node 2 에서 4GiB의 대규모 페이지가 예약됩니다.

    4. 이전 단계에서 생성한 스크립트를 실행 파일로 만듭니다.

      # chmod +x /etc/systemd/hugetlb-reserve-pages.sh
    5. 부팅 시 대규모 페이지 예약을 활성화합니다.

      # systemctl enable hugetlb-gigantic-pages
  4. virsh edit 명령을 사용하여 최적화하려는 VM의 XML 구성을 편집합니다. 이 예제 super-VM:

    # virsh edit super-vm
  5. 다음과 같은 방식으로 VM의 XML 구성을 조정합니다.

    1. 8개의 정적 vCPU를 사용하도록 VM을 설정합니다. 이 작업을 수행하려면 <vcpu/> 요소를 사용합니다.
    2. 각 vCPU 스레드를 토폴로지에서 미러링하는 해당 호스트 CPU 스레드에 고정합니다. 이렇게 하려면 < cputune> 섹션에서 <vcpupin/ > 요소를 사용합니다.

      위의 virsh 기능 유틸리티에 표시된 대로 호스트 CPU 스레드는 해당 코어에서 순차적으로 정렬되지 않습니다. 또한 vCPU 스레드는 동일한 NUMA 노드에서 사용 가능한 최고 수준의 호스트 코어 세트에 고정되어야 합니다. 테이블 그림은 아래의 샘플 토폴로지 섹션을 참조하십시오.

      a 및 b. 단계를 위한 XML 구성은 다음과 유사합니다.

      <cputune>
        <vcpupin vcpu='0' cpuset='1'/>
        <vcpupin vcpu='1' cpuset='4'/>
        <vcpupin vcpu='2' cpuset='2'/>
        <vcpupin vcpu='3' cpuset='5'/>
        <vcpupin vcpu='4' cpuset='7'/>
        <vcpupin vcpu='5' cpuset='10'/>
        <vcpupin vcpu='6' cpuset='8'/>
        <vcpupin vcpu='7' cpuset='11'/>
        <emulatorpin cpuset='6,9'/>
      </cputune>
    3. 1GiB 대규모 페이지를 사용하도록 VM을 설정합니다.

      <memoryBacking>
        <hugepages>
          <page size='1' unit='GiB'/>
        </hugepages>
      </memoryBacking>
    4. 호스트의 해당 NUMA 노드의 메모리를 사용하도록 VM의 NUMA 노드를 구성합니다. 이렇게 하려면 < numatune/> 섹션에서 <memnode /> 요소를 사용합니다.

      <numatune>
        <memory mode="preferred" nodeset="1"/>
        <memnode cellid="0" mode="strict" nodeset="0"/>
        <memnode cellid="1" mode="strict" nodeset="1"/>
      </numatune>
    5. CPU 모드가 host-passthrough 로 설정되어 있고 CPU가 passthrough 모드에서 캐시를 사용하는지 확인합니다.

      <cpu mode="host-passthrough">
        <topology sockets="2" cores="2" threads="2"/>
        <cache mode="passthrough"/>
  6. 결과적으로 VM의 XML 구성에 다음과 유사한 섹션이 포함되어 있는지 확인합니다.

    [...]
      <memoryBacking>
        <hugepages>
          <page size='1' unit='GiB'/>
        </hugepages>
      </memoryBacking>
      <vcpu placement='static'>8</vcpu>
      <cputune>
        <vcpupin vcpu='0' cpuset='1'/>
        <vcpupin vcpu='1' cpuset='4'/>
        <vcpupin vcpu='2' cpuset='2'/>
        <vcpupin vcpu='3' cpuset='5'/>
        <vcpupin vcpu='4' cpuset='7'/>
        <vcpupin vcpu='5' cpuset='10'/>
        <vcpupin vcpu='6' cpuset='8'/>
        <vcpupin vcpu='7' cpuset='11'/>
        <emulatorpin cpuset='6,9'/>
      </cputune>
      <numatune>
        <memory mode="preferred" nodeset="1"/>
        <memnode cellid="0" mode="strict" nodeset="0"/>
        <memnode cellid="1" mode="strict" nodeset="1"/>
      </numatune>
      <cpu mode="host-passthrough">
        <topology sockets="2" cores="2" threads="2"/>
        <cache mode="passthrough"/>
        <numa>
          <cell id="0" cpus="0-3" memory="2" unit="GiB">
            <distances>
              <sibling id="0" value="10"/>
              <sibling id="1" value="21"/>
            </distances>
          </cell>
          <cell id="1" cpus="4-7" memory="2" unit="GiB">
            <distances>
              <sibling id="0" value="21"/>
              <sibling id="1" value="10"/>
            </distances>
          </cell>
        </numa>
      </cpu>
    </domain>
  7. 선택 사항: 해당 툴 및 유틸리티를 사용하여 VM 최적화의 영향을 평가하여 VM의 성능을 테스트합니다.

토폴로지 샘플

  • 다음 표에서는 고정해야 하는 vCPU와 호스트 CPU 간의 연결을 보여줍니다.

    표 14.1. 호스트 토폴로지

    CPU 스레드

    0

    3

    1

    4

    2

    5

    6

    9

    7

    10

    8

    11

    코어

    0

    1

    2

    3

    4

    5

    소켓

    0

    1

    NUMA 노드

    0

    1

    표 14.2. VM 토폴로지

    vCPU 스레드

    0

    1

    2

    3

    4

    5

    6

    7

    코어

    0

    1

    2

    3

    소켓

    0

    1

    NUMA 노드

    0

    1

    표 14.3. 결합된 호스트 및 VM 토폴로지

    vCPU 스레드

     

    0

    1

    2

    3

     

    4

    5

    6

    7

    호스트 CPU 스레드

    0

    3

    1

    4

    2

    5

    6

    9

    7

    10

    8

    11

    코어

    0

    1

    2

    3

    4

    5

    소켓

    0

    1

    NUMA 노드

    0

    1

    이 시나리오에는 2개의 NUMA 노드와 8개의 vCPU가 있습니다. 따라서 4개의 vCPU 스레드를 각 노드에 고정해야 합니다.

    또한 Red Hat은 호스트 시스템 작업을 위해 각 노드에서 적어도 하나의 CPU 스레드를 사용할 수 있도록 하는 것이 좋습니다.

    이 예에서 각 NUMA 노드에는 각각 2개의 호스트 CPU 스레드가 있는 3개의 코어가 있으므로 노드 0의 세트는 다음과 같이 변환됩니다.

    <vcpupin vcpu='0' cpuset='1'/>
    <vcpupin vcpu='1' cpuset='4'/>
    <vcpupin vcpu='2' cpuset='2'/>
    <vcpupin vcpu='3' cpuset='5'/>

14.5.5. 커널 동일 페이지 병합 비활성화

커널 동일 페이지 병합(KSM)은 메모리 밀도를 향상하지만 CPU 사용률을 높이며 워크로드에 따라 전반적인 성능에 부정적 영향을 미칠 수 있습니다. 이러한 경우 KSM을 비활성화하여 VM(가상 머신) 성능을 향상시킬 수 있습니다.

요구 사항에 따라 단일 세션에서 KSM을 비활성화하거나 영구적으로 설정할 수 있습니다.

절차

  • 단일 세션에서 KSM을 비활성화하려면 systemctl 유틸리티를 사용하여 ksmksmtuned 서비스를 중지합니다.

    # systemctl stop ksm
    
    # systemctl stop ksmtuned
  • KSM을 영구적으로 비활성화하려면 systemctl 유틸리티를 사용하여 ksmksmtuned 서비스를 비활성화합니다.

    # systemctl disable ksm
    Removed /etc/systemd/system/multi-user.target.wants/ksm.service.
    # systemctl disable ksmtuned
    Removed /etc/systemd/system/multi-user.target.wants/ksmtuned.service.
참고

KSM을 비활성화하기 전에 VM 간에 공유되는 메모리 페이지는 공유됩니다. 공유를 중지하려면 다음 명령을 사용하여 시스템의 모든 PageKSM 페이지를 삭제합니다.

# echo 2 > /sys/kernel/mm/ksm/run

익명 페이지가 KSM 페이지를 교체한 후 khugepaged 커널 서비스는 VM의 물리적 메모리에서 투명한 대규모 페이지를 다시 빌드합니다.

Red Hat logoGithubRedditYoutubeTwitter

자세한 정보

평가판, 구매 및 판매

커뮤니티

Red Hat 문서 정보

Red Hat을 사용하는 고객은 신뢰할 수 있는 콘텐츠가 포함된 제품과 서비스를 통해 혁신하고 목표를 달성할 수 있습니다.

보다 포괄적 수용을 위한 오픈 소스 용어 교체

Red Hat은 코드, 문서, 웹 속성에서 문제가 있는 언어를 교체하기 위해 최선을 다하고 있습니다. 자세한 내용은 다음을 참조하세요.Red Hat 블로그.

Red Hat 소개

Red Hat은 기업이 핵심 데이터 센터에서 네트워크 에지에 이르기까지 플랫폼과 환경 전반에서 더 쉽게 작업할 수 있도록 강화된 솔루션을 제공합니다.

© 2024 Red Hat, Inc.