본문 바로가기

CS/데이터베이스

DB Server의 CPU 사용률이 높은 상황 - 2

동시 접속자 수 증가로 인한 성능 문제

동시 접속자의 수가 증가되면서 TPS가 높아진다면, CPU의 부하가 증가하게 될 것입니다. 많은 사용자가 동시에 시스템에 접속해 요청을 보낼 경우 초당 처리 건수(TPS, Transaction Per Second)가 증가합니다. 동시에 실행되는 SQL 쿼리 수가 많아져 DB 서버의 부하가 급격하게 증가합니다.

동시 접속자 수 증가로 발생될 수 있는 문제

컨텍스트 스위칭이 증가할 것입니다. 스레드가 많아질수록 CPU는 작업간 전환을 빈번하게 수행하며, 이 과정에서 캐시 미스 및 CPU 자원이 낭비됩니다. 특히, 전환 횟수가 증가하게 되면서 CPU 효율이 떨어지고 L1/L2 캐시 미스가 발생합니다.

디스크 I/O가 증가합니다. 메모리에 없는 데이터를 디스크에서 읽어와야 하며, 이때 CPU는 I/O 요청 처리와 대기 상태 전환을 반복하게 될 것입니다. 디스크에서 데이터를 읽어오는 순간은 시스템에서 I/O Wait Time으로 측정됩니다.

Page Fault가 발생할 것 입니다. 필요한 데이터가 메모리에 존재하지 않으면 페이지 폴트가 발생합니다. 그때 디스크 스왑이 이루어져 CPU가 더 많은 작업을 하게 됩니다. 이때, 프로세스가 디스크에서 데이터를 읽어와야하기에 커널의 개입이 필요하고 CPU가 개입하게 됩니다.

CPU 사용률의 비정상적으로 증가할 것입니다. 실제 연산보다는 I/O 대기, 인터럽트 처리 등 시스템 오버헤드로 인해 CPU 사용률이 높아지는 현상이 발생하게 될 것입니다.

커널 레벨 오버헤드가 증가합니다. 디스크 접근하면서 OS 커널은 버퍼링, 캐시 제어, 인터럽트 처리 등 다양한 작업을 수행하게 되면서 CPU를 점유하게 됩니다.

디스크 접근을 줄이고, CPU 부하를 줄이는 방안

1. innodb_buffer_pool_size를 확대합니다.

InnoDB는 테이블과 인덱스 데이터를 디스크가 아닌 메모리로 캐싱을 하게 되며, 이때 사용하는 공간이 innodb_buffer_pool_size입니다. 일반적으로 전체 서버 메모리의 60% ~ 80% 까지 설정을 합니다.

2. Buffer Pool Hit Ratio 확인합니다.

InnoDB가 디스크 대신 메모리에서 데이터를 얼마나 자주 읽는지를 나타냅니다. 이상적인 적중률을 99%이상이고, 낮은 적중률은 디스크 접근이 많다는 의미이고 메모리 확장이 필요합니다.

3. Cold Data 분리합니다.

자주 사용되지 않는 데이터는 별도 테이블 또는 DB로 분리해 캐싱 공간 낭비를 줄입니다. 최근 3개월간 데이터를 메인 테이블에 유지하고 과거 데이터는 별도 아카이빙하는 테이블로 이전합니다.

4. Connection Pool 제한 및 Queue 처리를 합니다.

동시 접속자가 많아질 경우 무한한 커넥션 생성으로 리소스를 낭비시킬 수 있습니다. 이는 max_connections를 적절히 제한하고, 요청은 Queue 기반으로 처리하는 방식이 필요합니다.

5. 첫번째에서 말한 서브쿼리는 CPU 및 디스 자원을 많이 소비하게 됩니다.

가능하다면 JOIN, Derived Table을 사용해 옵티마이저가 더 나은 실행계획을 선택할 수 있게 유도해야합니다.