본문으로 건너뛰기

20.2 OS 튜닝

OS에 따라 설정 방법은 다르지만, 다음과 같은 유형의 구성에 주목하고 부족한 것이 있으면 설정 값을 늘린다.

  • 라지 페이지 메모리
  • 오픈 가능한 파일 수
  • 프로세스 수 / 스레드 수
  • 데이터 세그먼트 크기 / 스택 크기
  • TCP / IP 파라미터

Linux의 Large Page Memory 조정

옛날의 메인 프레임에서부터 지금까지 OS의 메모리 페이지 사이즈는 4 KB이다. 이 4 KB 단위는 메인 프레임 아키텍처에서 Magic number이며, 메인 프레임 시스템 전체가 바로 4 KB 로 튜닝 되었다. 예를 들면 I/O 명령의 처리 단위는 4 KB 이고, 디스크 장치의 블록 사이즈도 4 KB 가 최적 값이다. 키보드를 입력하면 전송되는 데이터와 응답 화면에 표시되는 데이터양도 4 KB 이하였다. 즉, 모든 I/O 처리나 메모리 처리를 4 KB 단위이기 때문에 4 KB 로 처리하면 최고의 성능을 얻을 수 있는 구조였다.

하지만 세월이 흘러 IT 환경이 변화하면서 데이터 크기가 점점 커지게 되고, 메모리 가격도 저렴해짐에 따라 현재 4 KB의 페이지 크기는 적합하지 않게 되었다. 수십 GB에서 몇 TB의 메모리를 탑재하는 서버도 4 KB 단위로 가상 메모리를 관리하면, 페이지 테이블 크기가 커져서 메모리에 부담을 줄 뿐만 아니라 페이징 등의 처리에서 오버헤드가 발생한다.

최근에 64 비트 시스템에서는 라지 메모리 페이지만 사용해도 높은 성능향상을 기대할 수 있다. 기본적인 메모리 페이지 사이즈는 4kb 이다. 만약 이 상태로 대용량의 메모리를 사용하게 될 경우 메모리 어드레싱 횟수가 많이 증가한다. 예를 들면 1기가(1,048,576 Kbyte)라고 하더라도 262,144개의 메모리 페이지가 필요하며 이것은 시스템에 큰 오버헤드가 발생한다.

리눅스에서는 빈번하게 발생하는 메모리 페이지 맵핑의 오버헤드를 줄이기 위하여 라지 메모리 페이지는 디스크에 스왑핑하지 않는다.

힙 영역에 대하여 디스크에 스왑을 하게 되면 애플리케이션 성능에 큰 영향을 미치기 때문에 라지 메모리 페이지는 성능에 매우 중요한 요소가 된다.

라지 페이지 메모리 크기는 하드웨어에 따라 다르겠지만 2MB~ 256 MB이다. 이 값은 서버 환경에 따라 달라서 사용하고 있는 서버 환경에 적합한 값을 찾아서 적용해야 한다.

대부분 자바 가상 머신들은 리눅스에서 라지 메모리 페이지를 지원하고 있다. 이 값의 설정은 쉽지 않기 때문에 전문가와 논의하여 진행해야 한다.

라지 페이지 메모리 즉 Huge Page를 설정하게 되면 리눅스 상에 다른 일반 애플리케이션에서는 사용할 수 없게 되고 지정된 애플리케이션에서만 사용하게 된다.

이 메모리는 특정 애플리케이션에 할당되어 있기 때문에 다른 애플리케이션들은 메모리가 제거된 것처럼 보이게 된다.

라지 페이지 메모리 설정 방법

  1. JVM에 Large Page 메모리 적용

    Sun JVM과 Open JDK에서 Large-Page를 사용하려면 다음과 같은 옵션이 필요하다.

    -XX:+UseLargePages

  2. 커널 파라미터 설정

    /etc/sysctl.conf 파일에 아래의 3개의 커널 파라미터를 추가한다.

    • kernel.shmmax = n

      n값은 시스템에서 허용되는 공유 메모리 세그먼트의 최대 바이트 값이 된다. 사용하고 싶은 최대 JVM heap 사이즈 값이 필요하다. 또는 시스템의 총 메모리 용량을 설정할 수도 있다.

    • vm.nr_hugepages = n

      n값은 Large-Page의 값이다. Large-Page의 사이즈는 /proc/meminfo를 참조하라.

    • vm.huge_tlb_shm_group = gid

      gid는 Large-Page 접근할 수 있는 그룹 ID이다. 이 설정으로 라지 메모리세그먼트 접근을 제한할 수 있다.

  3. limits.conf 파라미터 설정

    ‘/etc/security/limits.conf’의 memlock의 제한값 설정:

    <username> soft memlock n

    <username> hard memlock n

    <username>에는 JVM 사용자 계정이며, nvm.nr_hugepages의 페이지 값과 /proc/meminfo에 KB로 기재되어 있는 페이지 사이즈를 곱한 값을 설정한다.

  4. 설정을 적용

    sysctl –p

  5. 리부팅

    OS에 메모리페이지를 할당한 후 안전한 시스템 운영을 위하여 시스템을 리부팅한다.

  6. 적용 값 확인

    Large-Page가 할당되었다면, /proc/meminfo로 HugePages_Total에 ‘0’ 이 아닌 숫자가 표시되게 된다. ‘0’으로 표시되어 있다면 Large-Page는 사용되지 않은 것으로 구성에 문제가 있는 것이다.

라지 메모리 페이지 설정 예

서버에 8 GB 메모리를 탑재하고 있다고 가정하자. JBoss EAP 6의 JVM과 MySQL 데이터베이스가 공유할 수 있도록 6 GB를 할당한다.

  1. Hugepagesize확인

    ‘/proc/meminfo’에 있는 페이지 사이즈는 2 MB이다(Hugepagesize: 2048 KB).

    # *cat /proc/meminfo*

    … 생략 …

    HugePages_Total: 0

    HugePages_Free: 0

    HugePages_Rsvd: 0

    HugePages_Surp: 0

    *Hugepagesize: 2048 kB*

    DirectMap4k: 685952 kB

    DirectMap2M: 16082944 kB
  2. /etc/sysctl.conf 설정

    • 최대 공유 메모리 세그먼트 사이즈를 8 GB로 변경 kernel.shmmax = 8589934592

    • 사용자 계정에서 접근할 수 있도록, hugetlb_shm_group에 gid를 설정 vm.hugetlb_shm_group = 501

    • JVM와 MySQL로 공유할 수 있도록, 2 MB페이지를 3072개 사용하여 6GB 할당

      vm.nr_hugepages = 3072

      kernel.shmmax = 8589934592

      vm.hugetlb_shm_group = 501

      vm.nr_hugepages = 3072
    • 계산식:1024 * 1024 * 1024 * 8 = 8589934592

  3. /etc/security/limits.conf 설정

    • JVM와 MySQL가 Large-Page메모리에 액세스 할 수 있도록 memlock에 제한 값 추가

      *jboss soft memlock 6291456*

      *jboss hard memlock 6291456*

      *mysql soft memlock 6291456*

      *mysql hard memlock 6291456*

      *root soft memlock 6291456*

      *root hard memlock 6291456*
    • 계산식 : 2048KB는 페이지 사이즈

  4. /etc/group 설정:

    사용자 계정에 공유 메모리 세그먼트 접근 권한을 주려면 ’/etc/group’의 501(hugetlb) 그룹에 JBoss와 MySQL를 추가한다.

    … 생략 …

    *hugetlb:x:501:jboss,mysql*

리눅스에서 가상 메모리 매니저 튜닝

Linux에서 가상 메모리 매니저 튜닝도 가능하다. 간단히 설정을 변경하여 성능을 향상할 수 있다.

Linux 2.6 커널의 swappiness라는 새로운 커널 파라미터가 추가되어 관리자가 Linux 스왑 처리 조정이 가능하다. 이 파라미터는 0 ~ 100 사이의 값을 설정하지만, 값이 클수록 페이지 스와핑을 많이 하고 값이 작으면 많은 메모리가 애플리케이션에 확보된다는 것이다. 메모리 스와핑이 너무 많이 발생하면 시스템 성능이 낮아지게 된다.

/etc/sysctl.conf 에 vm.swappiness의 값을 1로 설정하면 애플리케이션이 디스크에 스와핑하는 것을 막을 수가 있다.

애플리케이션 서버나 데이터베이스 서버와 같이 높은 성능을 요구하는 시스템에서 자주 스와핑이 발생하지 않도록 하는 것이 좋다. 스와핑이 발생하는 것을 최소화하기 위해 값을 0 ~ 10 정도의 값을 사용할 것을 권장한다.

vm.swappiness의 값을 확인하는 방법은 다음과 같다. 0으로 하면 실제 메모리를 다 사용할 때까지 스와핑 하지 않게 된다.

vm.swappiness 설정

  1. swappiness 값을 확인

    현재 swappiness 값을 확인(기본 60)

    # cat /proc/sys/vm/swappiness

    60
  2. vm.swappiness 설정 변경

    파일에 추가(10으로 설정하여 커널 파라미터를 반영)

    # vi /etc/sysctl.conf

    … 생략 …

    vm.swappiness = 10

    … 생략 …

    또는

    sysctl -w vm.swappiness=10

  3. 설정을 반영

    sysctl -p

    vm.swappiness의 기본값은 60인데 기본값의 절반인 10~15 정도로 줄이는 것이 스왑 사용량을 더 줄일 수 있다. 0으로 설정할 경우 스와핑하지 않기 때문에 어떤 상황에서는 메모리 부족이 빨리 발생될 수 있고 심하면 시스템이 멈추는 현상이 발생할 수도 있다.

    이처럼 튜닝할 경우 트레이드 오프가 있기 때문에 이런 튜닝 값들은 테스트를 통해 최적 값을 찾아야 한다. swappiness값을 줄일 때 주의할 점은 메모리가 부족한 상황이 발생하였을 때 시스템이 가용메모리 확보를 위해 스와핑하지 않기 때문에 시스템이 느려질 수도 있다.