Amazon Elastic Compute Cloud
Linux 인스턴스용 사용 설명서

운영 체제 최적화

향상된 네트워킹을 지원하는 인스턴스에서 네트워크 성능을 최대화하려는 경우 기본 운영 체제 구성을 수정해야 할 수도 있습니다. 높은 수준의 네트워크 성능을 필요로 하는 애플리케이션에는 다음 구성 변경을 권장합니다.

이러한 운영 체제 최적화 외에도, 네트워크 트래픽의 최대 전송 단위(MTU)를 고려하여 워크로드 및 네트워크 아키텍처에 맞게 조정해야 합니다. 자세한 내용은 EC2 인스턴스에 대한 네트워크 MTU(최대 전송 단위) 단원을 참조하십시오.

AWS는 클러스터 배치 그룹에서 시작된 인스턴스 간의 평균 왕복 지연 시간(50us)과 99.9 백분위 테일 지연 시간(200us)을 정기적으로 측정합니다. 애플리케이션에서 일관되게 낮은 지연 시간을 요구하는 경우 고정 성능 Nitro 기반 인스턴스에 최신 버전의 ENA 드라이버를 사용하는 것이 좋습니다.

이러한 절차는 Amazon Linux 2 및 Amazon Linux AMI용으로 작성되었습니다. 하지만 커널 버전이 3.9 이상인 다른 Linux 배포판에서도 작동할 수 있습니다. 자세한 내용은 해당 시스템 관련 설명서를 참조하십시오.

향상된 네트워킹을 지원하도록 Amazon Linux 인스턴스를 최적화하는 방법

  1. 인스턴스의 클록 소스를 확인합니다.

    cat /sys/devices/system/clocksource/clocksource0/current_clocksource
  2. 클록 소스가 xen이면 다음 하위 단계를 완료합니다. 그렇지 않으면 단계 3로 건너뜁니다.

    1. GRUB 구성을 편집하여 xen_nopvspin=1clocksource=tsc를 커널 부트 옵션에 추가합니다.

      • Amazon Linux 2의 경우 아래와 같이 /etc/default/grub 파일을 편집하고 이러한 옵션을 GRUB_CMDLINE_LINUX_DEFAULT 줄에 추가합니다.

        GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8 net.ifnames=0 biosdevname=0 nvme_core.io_timeout=4294967295 xen_nopvspin=1 clocksource=tsc" GRUB_TIMEOUT=0
      • Amazon Linux AMI의 경우 아래와 같이 /boot/grub/grub.conf 파일을 편집하고 이러한 옵션을 kernel 줄에 추가합니다.

        kernel /boot/vmlinuz-4.14.62-65.117.amzn1.x86_64 root=LABEL=/ console=tty1 console=ttyS0 selinux=0 nvme_core.io_timeout=4294967295 xen_nopvspin=1 clocksource=tsc
    2. (Amazon Linux 2에만 해당) 이러한 변경 사항이 적용되도록 GRUB 구성 파일을 다시 빌드합니다.

      sudo grub2-mkconfig -o /boot/grub2/grub.cfg
  3. 해당 인스턴스 유형이 EC2 인스턴스에 대한 프로세서 상태 제어에서 지원되는 유형으로 나열되는 경우 지연 시간이 짧은 시스템 성능을 유지하려면 시스템에서 C 상태가 심화되지 않도록 해야 합니다. 자세한 내용은 C 상태 심화 제한을 통한 고성능 및 저 지연 시간 단원을 참조하십시오.

    1. GRUB 구성을 편집하여 intel_idle.max_cstate=1을 커널 부트 옵션에 추가합니다.

      • Amazon Linux 2의 경우 아래와 같이 /etc/default/grub 파일을 편집하고 이 옵션을 GRUB_CMDLINE_LINUX_DEFAULT 줄에 추가합니다.

        GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8 net.ifnames=0 biosdevname=0 nvme_core.io_timeout=4294967295 xen_nopvspin=1 clocksource=tsc intel_idle.max_cstate=1" GRUB_TIMEOUT=0
      • Amazon Linux AMI의 경우 아래와 같이 /boot/grub/grub.conf 파일을 편집하고 이 옵션을 kernel 줄에 추가합니다.

        kernel /boot/vmlinuz-4.14.62-65.117.amzn1.x86_64 root=LABEL=/ console=tty1 console=ttyS0 selinux=0 nvme_core.io_timeout=4294967295 xen_nopvspin=1 clocksource=tsc intel_idle.max_cstate=1
    2. (Amazon Linux 2에만 해당) 이러한 변경 사항이 적용되도록 GRUB 구성 파일을 다시 빌드합니다.

      sudo grub2-mkconfig -o /boot/grub2/grub.cfg
  4. 예약된 커널 메모리가 충분하여 패킷 버퍼 할당의 높은 속도를 유지할 수 있는지 확인합니다(기본값은 너무 작을 수 있음).

    1. 선택한 편집기에서 (root로 또는 sudo를 사용하여) /etc/sysctl.conf 파일을 엽니다.

    2. 해당 인스턴스 유형에 맞는 예약된 커널 메모리 값(KB)을 사용하여 이 파일에 vm.min_free_kbytes 줄을 추가합니다. 기본적으로 이 값을 가용 시스템 메모리의 1-3%로 설정하고 애플리케이션 요건에 맞춰 이 값을 높거나 낮게 조정해야 합니다.

      vm.min_free_kbytes = 1048576
    3. 다음 명령을 사용하여 이 구성을 적용합니다.

      sudo sysctl -p
    4. 다음 명령을 사용하여 설정이 적용되었는지 확인합니다.

      sudo sysctl -a 2>&1 | grep min_free_kbytes
  5. 인스턴스를 재부팅하여 새 구성을 로드합니다.

    sudo reboot
  6. (선택 사항) 모두가 동일 NUMA 노드에 속하는 다양한 CPU와 연결되도록 패킷 수신 인터럽트를 수동으로 분배합니다. 하지만 irqbalancer가 전역적으로 비활성화되어 있으므로 이 작업을 수행할 때 각별히 주의해야 합니다.

    참고

    이 단계의 구성 변경 사항은 재부팅 후에는 유지되지 않습니다.

    1. smp_affinity.sh라는 파일을 생성한 후 그 안에 다음 코드 블록을 붙여 넣습니다.

      #/bin/sh service irqbalance stop affinity_values=(00000001 00000002 00000004 00000008 00000010 00000020 00000040 00000080) irqs=($(grep eth /proc/interrupts|awk '{print $1}'|cut -d : -f 1)) irqLen=${#irqs[@]} for (( i=0; i<${irqLen}; i++ )); do echo $(printf "0000,00000000,00000000,00000000,${affinity_values[$i]}") > /proc/irq/${irqs[$i]}/smp_affinity; echo "IRQ ${irqs[$i]} =" $(cat /proc/irq/${irqs[$i]}/smp_affinity); done
    2. 다음 명령으로 스크립트를 실행합니다.

      sudo bash ./smp_affinity.sh
  7. (선택 사항) 핸들에서 IRQ를 받는 vCPU가 과부하 상태인 경우 또는 애플리케이션 네트워크 처리가 CPU에 의존하는 경우 수신 패킷 스티어링(RPS)을 이용하여 네트워크 처리 부분을 다른 코어로 분담시킬 수 있습니다. NUMA 간에 노드가 잠기지 않도록 RPS에 사용되는 코어가 동일 NUMA 노드에 속해 있는지 확인합니다. 예를 들면 패킷 처리 시 코어 8-15개를 사용하려면 다음 명령을 사용합니다.

    참고

    이 단계의 구성 변경 사항은 재부팅 후에는 유지되지 않습니다.

    for i in `seq 0 7`; do echo $(printf "0000,00000000,00000000,00000000,0000ff00") | sudo tee /sys/class/net/eth0/queues/rx-$i/rps_cpus; done
  8. (선택 사항) 가능하면 동일 NUMA 노드에서 모든 처리를 유지합니다.

    1. numactl을 설치합니다.

      sudo yum install -y numactl
    2. 네트워크 처리 프로그램 실행 시 이 프로그램을 단일 NUMA 노드에 바인딩합니다. 예를 들면 다음 명령은 셸 스크립트인 run.sh를 NUMA 노드 0으로 바인딩합니다.

      numactl --cpunodebind=0 --membind=0 run.sh
    3. 하이퍼스레딩이 활성화된 경우 CPU 코어당 단일 하드웨어 스레드만 사용하도록 애플리케이션을 구성할 수 있습니다.

      • lscpu 명령을 사용하여 NUMA 노드로 매핑되는 CPU 코어를 볼 수 있습니다.

        lscpu | grep NUMA

        결과:

        NUMA node(s): 2 NUMA node0 CPU(s): 0-15,32-47 NUMA node1 CPU(s): 16-31,48-63
      • 다음 명령을 사용하여 물리적 CPU에 속하는 하드웨어 스레드를 볼 수 있습니다.

        cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list

        결과:

        0,32

        이 예에서는 스레드 0과 32가 CPU 0으로 매핑됩니다.

      • 스레드 32-47(실제로는 0-15와 동일한 CPU의 하드웨어 스레드)에서 실행되지 않도록 하려면 다음 명령을 사용합니다.

        numactl --physcpubind=+0-15 --membind=0 ./run.sh
  9. 다양한 트래픽 클래스에 대해 여러 탄력적 네트워크 인터페이스를 사용합니다. 예를 들어 백엔드 데이터베이스를 사용하는 웹 서버를 실행하려는 경우 탄력적 네트워크 인터페이스 하나를 웹 서버 프런트 엔드로 사용하고, 다른 하나를 데이터베이스 연결용으로 사용합니다.