Transparent Huge Pages가 데이터베이스 성능을 망치는 이유! 비활성화 하는 방법까지 총정리!

현대 IT 시스템에서 데이터베이스는 비즈니스의 핵심입니다. 데이터베이스의 성능은 서비스 응답 속도, 사용자 경험, 그리고 궁극적으로 기업의 수익과 직결됩니다. 이러한 데이터베이스 성능에 예상치 못한 영향을 미치는 요소 중 하나가 바로 ‘Transparent Huge Pages’ (THP)입니다. 리눅스 운영체제의 메모리 관리 기능 중 하나인 THP는 특정 애플리케이션의 성능을 향상시키기 위해 고안되었지만, 데이터베이스 시스템에서는 오히려 독이 될 수 있습니다. 이 글에서는 THP가 무엇인지, 왜 데이터베이스 성능에 부정적인 영향을 미치는지, 그리고 어떻게 관리해야 하는지에 대한 종합적인 가이드를 제공합니다.

Transparent Huge Pages란 무엇인가?

컴퓨터의 메모리는 ‘페이지’라는 작은 단위로 관리됩니다. 대부분의 리눅스 시스템에서 이 페이지의 기본 크기는 4KB입니다. 운영체제는 이 4KB 페이지를 사용하여 프로그램에 메모리를 할당하고 관리합니다. 그런데 페이지 크기가 작으면 메모리 주소를 변환하는 작업(TLB lookups)이 빈번하게 발생하여 오버헤드가 커질 수 있습니다.

이러한 오버헤드를 줄이기 위해 리눅스 커널은 ‘Huge Pages’라는 기능을 도입했습니다. Huge Pages는 2MB 또는 1GB와 같은 훨씬 큰 단위의 메모리 페이지를 사용합니다. 큰 페이지를 사용하면 TLB 캐시 미스 발생률이 줄어들어 메모리 접근 성능이 향상될 수 있습니다. 하지만 Huge Pages를 사용하려면 애플리케이션 개발자가 코드를 수정하거나, 시스템 관리자가 수동으로 Huge Pages를 설정하고 애플리케이션이 이를 사용하도록 구성해야 하는 번거로움이 있었습니다.

여기서 ‘Transparent Huge Pages’ (THP)가 등장합니다. THP는 이름 그대로 ‘투명하게’ Huge Pages의 이점을 제공하려는 목적으로 개발되었습니다. 시스템 관리자나 애플리케이션 개발자의 개입 없이, 운영체제가 자동으로 4KB 페이지를 2MB Huge Pages로 병합하고 관리하려고 시도합니다. 이는 주로 메모리를 많이 사용하고, 메모리 접근 패턴이 순차적인 과학 계산이나 고성능 컴퓨팅(HPC) 애플리케이션에서 성능 향상을 기대할 수 있도록 설계되었습니다.

데이터베이스 시스템에서 THP가 문제를 일으키는 이유

THP는 일반적인 애플리케이션에는 유용할 수 있지만, 데이터베이스 시스템에서는 대부분 문제를 일으킵니다. 그 이유는 데이터베이스의 메모리 사용 패턴이 일반적인 애플리케이션과는 다르기 때문입니다.

데이터베이스의 메모리 사용 패턴

데이터베이스는 일반적으로 대량의 메모리(버퍼 캐시, 공유 메모리 영역 등)를 사용하지만, 이 메모리에 접근하는 방식은 매우 ‘랜덤’하고 ‘분산적’입니다. 예를 들어, 데이터베이스는 특정 데이터 블록을 읽기 위해 버퍼 캐시의 특정 위치에 접근할 수 있지만, 다음 순간에는 완전히 다른 데이터 블록을 위해 다른 위치에 접근할 수 있습니다. 즉, 메모리 전체에 걸쳐 산발적으로 접근하는 패턴을 보입니다.

메모리 파편화와 성능 저하

THP는 4KB 페이지를 2MB 페이지로 병합하려고 시도합니다. 이 과정에서 운영체제는 연속된 4KB 페이지들을 찾아서 하나의 2MB Huge Page로 만듭니다. 하지만 데이터베이스의 메모리 사용 패턴이 랜덤하기 때문에, 연속된 2MB의 메모리 공간을 찾기 어렵습니다. THP는 이러한 상황에서도 계속해서 Huge Page를 만들려고 시도하며, 이 과정에서 불필요한 CPU 리소스를 소모하고 메모리 파편화를 심화시킬 수 있습니다.

메모리 파편화가 심해지면, 운영체제가 새로운 Huge Page를 할당하거나 기존 Huge Page를 관리하는 데 어려움을 겪게 됩니다. 이는 데이터베이스가 필요한 메모리 공간을 즉시 확보하지 못하게 만들고, 결과적으로 시스템 응답 속도를 저하시킵니다.

페이지 폴트와 락 경합

THP가 활성화된 상태에서 데이터베이스는 필요한 메모리 페이지를 찾지 못하고 ‘페이지 폴트’를 더 자주 발생시킬 수 있습니다. 페이지 폴트가 발생하면 운영체제는 디스크에서 데이터를 읽어와 메모리에 로드해야 하는데, 이 과정에서 I/O 대기가 발생하여 성능이 크게 저하됩니다.

또한, THP는 Huge Page를 할당하고 해제하는 과정에서 커널 내부의 락(lock)을 사용합니다. 데이터베이스와 같이 메모리를 활발하게 사용하는 애플리케이션에서는 이러한 락에 대한 경합이 빈번하게 발생할 수 있습니다. 락 경합은 CPU 코어들이 서로 자원을 기다리게 만들고, 멀티코어 시스템의 이점을 제대로 활용하지 못하게 하여 전체적인 처리량을 감소시킵니다.

스왑 발생 증가

THP는 4KB 페이지를 2MB Huge Page로 만들려고 하기 때문에, 메모리에서 사용할 수 있는 ‘연속적인’ 공간이 부족해지면 운영체제는 더 작은 4KB 페이지를 스왑(swap) 영역으로 내보내려고 합니다. 문제는 2MB Huge Page는 스왑이 불가능하다는 점입니다. 따라서 운영체제는 스왑 가능한 4KB 페이지를 찾기 위해 더 많은 노력을 기울이게 되고, 이 과정에서 불필요한 스왑이 발생하여 디스크 I/O가 급증하고 시스템 전반의 성능이 치명적으로 저하될 수 있습니다.

다양한 데이터베이스에 미치는 영향

이러한 문제점들은 거의 모든 관계형 데이터베이스(RDBMS)와 NoSQL 데이터베이스에 공통적으로 적용됩니다. Oracle, MySQL, PostgreSQL, MongoDB, Redis 등 대부분의 주요 데이터베이스 벤더는 THP를 비활성화할 것을 권장합니다. 특히 Oracle AWR(Automatic Workload Repository) 리포트에서 ‘hugepages’ 관련 경고나 ‘swap activity’ 증가가 보인다면 THP의 영향을 의심해 볼 수 있습니다.

THP 활성화 여부 확인 방법

현재 시스템에서 THP가 활성화되어 있는지 확인하는 방법은 간단합니다. 리눅스 터미널에서 다음 명령어를 사용합니다.

cat /sys/kernel/mm/transparent_hugepage/enabled

이 명령어를 실행하면 다음과 같은 결과 중 하나가 출력됩니다.

  • [always] madvise never: THP가 항상 활성화되어 있습니다.
  • always [madvise] never: THP가 madvise 모드로 활성화되어 있습니다. (애플리케이션이 명시적으로 요청할 때만 Huge Pages를 사용)
  • always madvise [never]: THP가 비활성화되어 있습니다.

데이터베이스 시스템에서는 [never] 상태가 권장됩니다.

cat /sys/kernel/mm/transparent_hugepage/defrag

이 명령어는 THP가 메모리 조각 모음(defragmentation)을 어떻게 처리하는지 보여줍니다. THP가 활성화되어 있다면 조각 모음 기능도 활성화되어 있을 가능성이 높으며, 이는 CPU 사용량 증가의 원인이 될 수 있습니다. 데이터베이스 시스템에서는 [never] 상태가 권장됩니다.

데이터베이스 성능을 위한 THP 비활성화 방법

대부분의 데이터베이스 시스템에서는 THP를 비활성화하는 것이 일반적인 권장 사항입니다. 비활성화하는 방법은 다음과 같습니다.

임시 비활성화

재부팅 전까지 THP를 임시로 비활성화하려면 다음 명령어를 사용합니다.

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

echo never > /sys/kernel/mm/transparent_hugepage/defrag

이 방법은 시스템을 재부팅하면 원래 설정으로 돌아가므로, 테스트 목적으로 사용하거나 영구 설정을 적용하기 전에 확인하는 용도로 좋습니다.

영구 비활성화

THP를 영구적으로 비활성화하려면 부팅 시마다 적용되도록 설정해야 합니다. 가장 일반적인 방법은 GRUB 설정 파일을 수정하는 것입니다.

  1. GRUB 설정 파일 편집 (경로는 운영체제 버전에 따라 다를 수 있습니다. CentOS/RHEL 계열은 /etc/default/grub, Ubuntu/Debian 계열은 /etc/default/grub 또는 /etc/grub.d/40_custom 등)
    sudo vi /etc/default/grub

  2. GRUB_CMDLINE_LINUX 라인을 찾아서 transparent_hugepage=never 옵션을 추가합니다.

    기존:


    GRUB_CMDLINE_LINUX="rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet"

    수정 후:


    GRUB_CMDLINE_LINUX="rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet transparent_hugepage=never"

  3. GRUB 설정을 업데이트합니다.

    CentOS/RHEL 7 이상:


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

    Ubuntu/Debian:


    sudo update-grub

  4. 시스템을 재부팅합니다.
    sudo reboot

  5. 재부팅 후, 다시 THP 활성화 여부를 확인하는 명령어로 비활성화되었는지 검증합니다.
    cat /sys/kernel/mm/transparent_hugepage/enabled

    결과가 always madvise [never] 로 표시되어야 합니다.

또 다른 방법으로는 rc.local 스크립트를 사용하거나, systemd 서비스를 생성하여 부팅 시마다 echo never 명령어를 실행하도록 할 수도 있습니다. 하지만 GRUB 설정을 통한 방법이 가장 일반적이고 권장되는 방식입니다.

THP와 명시적 대용량 페이지 Explicit Huge Pages의 차이점

THP와 혼동하기 쉬운 것이 ‘명시적 대용량 페이지’ (Explicit Huge Pages 또는 HugeTLB)입니다. 이 둘은 모두 Huge Pages를 사용하지만 작동 방식과 데이터베이스에 미치는 영향은 완전히 다릅니다.


Transparent Huge Pages THP

운영체제가 자동으로 4KB 페이지를 2MB Huge Page로 병합하려고 시도합니다. 이 과정은 애플리케이션에 투명하게 이루어지며, 시스템 부하와 메모리 파편화를 유발할 수 있습니다. 데이터베이스에는 대부분 부정적인 영향을 미칩니다.


Explicit Huge Pages 명시적 대용량 페이지

시스템 관리자가 사전에 특정 크기(예: 2MB 또는 1GB)의 Huge Pages를 할당하고, 애플리케이션(주로 데이터베이스)이 이 Huge Pages를 명시적으로 요청하여 사용합니다. 이 Huge Pages는 스왑되지 않으며, 한 번 할당되면 페이지 이동이나 병합 시도가 없어 오버헤드가 적습니다. Oracle, PostgreSQL 등 일부 데이터베이스는 이 명시적 Huge Pages를 사용하도록 설정하면 성능 향상 효과를 볼 수 있습니다. 이는 데이터베이스가 버퍼 캐시와 같은 핵심 메모리 영역을 미리 할당된 안정적인 Huge Pages에 배치할 수 있기 때문입니다.

결론적으로, 데이터베이스 시스템에서는 THP를 비활성화하고, 필요하다면 명시적 Huge Pages를 구성하여 사용하는 것이 일반적인 권장 사항입니다.

THP에 대한 흔한 오해와 사실

오해1 대용량 페이지는 무조건 좋다

대용량 페이지(Huge Pages) 자체는 TLB 미스 감소 등 성능상 이점을 제공할 수 있습니다. 하지만 ‘Transparent Huge Pages’ (THP)는 그 ‘투명성’ 때문에 데이터베이스와 같은 특정 워크로드에서는 문제를 일으킵니다. THP의 자동적인 페이지 병합 시도와 그로 인한 오버헤드가 문제입니다. 명시적 Huge Pages는 제대로 설정하면 데이터베이스에 도움이 될 수 있습니다.

오해2 THP는 항상 문제를 일으킨다

THP는 모든 애플리케이션에 해로운 것은 아닙니다. 메모리 접근 패턴이 순차적이고 대용량의 연속된 메모리를 사용하는 애플리케이션(예: 일부 과학 계산, HPC)에서는 THP가 성능 향상에 기여할 수 있습니다. 문제는 데이터베이스의 랜덤한 메모리 접근 패턴과 맞지 않는다는 것입니다.

오해3 메모리가 많으면 THP가 괜찮다

시스템 메모리가 아무리 많아도 THP의 근본적인 문제점(랜덤 액세스 패턴과의 불일치, CPU 오버헤드, 락 경합, 스왑 발생 가능성)은 사라지지 않습니다. 오히려 메모리가 많을수록 THP가 더 많은 리소스를 소모하며 Huge Page를 만들려고 시도하여 문제의 심각성을 키울 수 있습니다. 메모리 용량과 관계없이 데이터베이스에는 THP 비활성화가 권장됩니다.

전문가들의 조언과 권장 사항

데이터베이스 분야의 전문가들과 주요 벤더들은 대부분 프로덕션 환경의 데이터베이스 서버에서 THP를 비활성화할 것을 강력히 권장합니다. Oracle, MySQL, PostgreSQL, MongoDB 등 거의 모든 데이터베이스 시스템의 공식 문서 및 커뮤니티에서는 THP로 인한 성능 저하 사례를 언급하며 비활성화를 기본 설정으로 제시하고 있습니다.

전문가들은 다음과 같은 조언을 합니다.


THP 비활성화는 기본

데이터베이스 서버를 구축할 때 가장 먼저 확인하고 적용해야 할 설정 중 하나입니다. 대부분의 경우 THP를 비활성화하는 것으로 불필요한 성능 저하를 방지할 수 있습니다.


테스트 환경에서의 검증

THP를 비활성화하기 전, 가능하다면 테스트 환경에서 비활성화 전후의 성능 지표를 비교하여 실제로 개선이 있는지 확인하는 것이 좋습니다. 하지만 데이터베이스의 특성상 THP 비활성화는 거의 항상 긍정적인 영향을 미칩니다.


명시적 Huge Pages 고려

THP 비활성화 후에도 더 높은 성능이 필요하다면, 데이터베이스 벤더의 가이드에 따라 명시적 Huge Pages를 구성하는 것을 고려해볼 수 있습니다. 이는 특히 대용량 메모리를 사용하는 시스템에서 효과적일 수 있습니다.

자주 묻는 질문

Q.THP를 끄면 다른 애플리케이션 성능은 어떻게 되나요

THP를 끄는 것은 데이터베이스 서버에 설치된 다른 애플리케이션에도 영향을 미칠 수 있습니다. 하지만 대부분의 일반적인 웹 서버, 애플리케이션 서버 등은 THP의 이점을 크게 받지 못하거나, 오히려 THP로 인한 오버헤드 때문에 성능이 저하될 수도 있습니다. 따라서 대부분의 프로덕션 서버에서는 THP를 비활성화하는 것이 안정성과 예측 가능성 측면에서 더 유리합니다. 특정 애플리케이션이 THP의 이점을 명확히 받는다면 해당 애플리케이션만 Huge Pages를 사용하도록 별도로 구성하는 방법을 고려할 수 있습니다.

Q.THP를 켜고 데이터베이스 성능을 개선할 방법은 없나요

원칙적으로 THP는 데이터베이스의 메모리 접근 패턴과 상충하기 때문에, THP를 활성화한 상태에서 데이터베이스 성능을 개선하는 것은 매우 어렵거나 불가능에 가깝습니다. 차라리 THP를 비활성화하고, 필요하다면 명시적 Huge Pages를 설정하는 것이 데이터베이스 성능 최적화를 위한 올바른 접근 방식입니다.

Q.클라우드 환경에서는 어떻게 해야 하나요

AWS EC2, Google Cloud, Azure 등 클라우드 환경의 가상 머신에서도 THP는 기본적으로 활성화되어 있을 수 있습니다. 클라우드 환경에서도 온프레미스 서버와 마찬가지로 데이터베이스 서버를 운영한다면 THP를 비활성화하는 것이 강력히 권장됩니다. 클라우드 제공업체는 일반적으로 OS 수준의 설정 변경을 허용하므로, 위에서 설명한 방법대로 THP를 비활성화할 수 있습니다.

비용 효율적인 활용 방법

THP를 비활성화하는 것은 직접적인 비용 절감으로 이어지지 않을 수 있지만, 장기적으로는 시스템 운영의 비용 효율성을 크게 높일 수 있습니다.


성능 저하 방지를 통한 비용 절감

THP로 인한 불필요한 CPU 사용량 증가, 스왑 발생, 응답 시간 지연 등은 시스템 자원의 비효율적인 사용을 의미합니다. THP를 비활성화함으로써 이러한 성능 저하를 방지하고, 기존 하드웨어 리소스를 최대한 활용하여 추가적인 하드웨어 증설이나 고가의 성능 튜닝에 드는 비용을 절감할 수 있습니다.


예측 가능한 시스템 운영

THP로 인한 불규칙적인 성능 저하는 문제 해결에 많은 시간과 노력을 요구합니다. THP를 비활성화하면 시스템의 메모리 관리 방식이 더욱 예측 가능해지고 안정성이 향상되어, 장애 발생률을 낮추고 운영 및 유지보수 비용을 절감할 수 있습니다.


최적의 메모리 설정으로 시스템 자원 효율 극대화

THP를 비활성화하고, 필요에 따라 명시적 Huge Pages를 데이터베이스에 할당하는 것은 메모리 자원을 데이터베이스의 특성에 맞게 최적화하는 것입니다. 이는 시스템 자원의 효율성을 극대화하여 더 적은 리소스로 더 높은 성능을 달성할 수 있게 하며, 이는 궁극적으로 비용 효율적인 시스템 운영으로 이어집니다.


이 게시물이 얼마나 유용했습니까?

평점을 매겨주세요.

평균 평점 0 / 5. 투표 수 : 0

가장 먼저 게시물을 평가해보세요.

댓글 남기기